Recherche avancée de parcelles avec scoring
L'API Infoparcelle propose un système de scoring intelligent pour rechercher les parcelles les plus pertinentes selon vos critères. Cette recherche avancée utilise la méthode POST sur le même endpoint que la recherche classique, mais offre des capacités beaucoup plus puissantes.
Vue d'ensemble
L'endpoint POST /api/v1/parcelles/recherche permet de combiner :
- 🎯 Critères stricts : Contraintes obligatoires (filtres WHERE SQL)
- ⭐ Critères indicatifs : Préférences qui influencent le score (système de ranking)
- 📊 Score de pertinence : Classement de 0 à 100 pour chaque parcelle
Avantages du scoring
- ✅ Résultats plus pertinents : Les meilleures correspondances en premier
- ✅ Flexibilité : Combinez contraintes obligatoires et préférences
- ✅ Intelligence : Le système calcule automatiquement la pertinence
- ✅ Personnalisation : Ajustez les poids en fonction de vos besoins
Différence entre mode strict et indicatif
Mode STRICT (indicatif: false)
Filtre WHERE SQL classique. Seules les parcelles correspondant exactement au critère sont retournées.
{
"annee_construction": {
"min": 1990,
"max": 2020,
"indicatif": false // ❌ STRICT : Exclut toute parcelle hors 1990-2020
}
}
Mode INDICATIF (indicatif: true)
Système de scoring. Les parcelles sont classées par pertinence selon leur correspondance au critère.
{
"annee_construction": {
"min": 1990,
"max": 2020,
"indicatif": true // ⭐ SCORING : Favorise 1990-2020, mais inclut les autres
}
}
Résultat : Une parcelle de 2018 aura un score élevé, une de 1985 ou 2025 aura un score plus faible, mais sera quand même retournée.
Recherche basique avec scoring
- cURL
- JavaScript
- PHP
- Python
curl -X POST \
"https://app.infoparcelle.fr/api/v1/parcelles/recherche" \
-H "Authorization: Bearer VOTRE_CLE_API" \
-H "Content-Type: application/json" \
-d '{
"filtres": {
"code_postal": {
"value": "75008"
},
"superficie": {
"min": 300,
"max": 800,
"indicatif": true
},
"dpe_energie": {
"value": "C,D",
"indicatif": true
}
},
"pagination": {
"limite": 20
},
"options": {
"champ_tri": "score_pertinence",
"ordre_tri": "desc",
"champs": ["cadastre_id", "superficie", "score_pertinence"]
}
}'
const apiKey = process.env.INFOPARCELLE_API_KEY;
const response = await fetch(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
filtres: {
code_postal: {
value: '75008'
},
superficie: {
min: 300,
max: 800,
indicatif: true
},
dpe_energie: {
value: 'C,D',
indicatif: true
}
},
pagination: {
limite: 20
},
options: {
champ_tri: 'score_pertinence',
ordre_tri: 'desc',
champs: ['cadastre_id', 'superficie', 'score_pertinence']
}
})
}
);
const parcelles = await response.json();
// Afficher les résultats triés par score
parcelles.forEach(p => {
console.log(`Score: ${p.score_pertinence}/100 - ${p.cadastre_id} (${p.superficie} m²)`);
});
<?php
$apiKey = getenv('INFOPARCELLE_API_KEY');
$data = [
'filtres' => [
'code_postal' => [
'value' => '75008'
],
'superficie' => [
'min' => 300,
'max' => 800,
'indicatif' => true
],
'dpe_energie' => [
'value' => 'C,D',
'indicatif' => true
]
],
'pagination' => [
'limite' => 20
],
'options' => [
'champ_tri' => 'score_pertinence',
'ordre_tri' => 'desc',
'champs' => ['cadastre_id', 'superficie', 'score_pertinence']
]
];
$options = [
'http' => [
'header' => [
"Authorization: Bearer $apiKey",
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
false,
$context
);
$parcelles = json_decode($response, true);
// Afficher les résultats triés par score
foreach ($parcelles as $p) {
echo "Score: {$p['score_pertinence']}/100 - {$p['cadastre_id']} ({$p['superficie']} m²)\n";
}
import os
import requests
api_key = os.getenv('INFOPARCELLE_API_KEY')
data = {
'filtres': {
'code_postal': {
'value': '75008'
},
'superficie': {
'min': 300,
'max': 800,
'indicatif': True
},
'dpe_energie': {
'value': 'C,D',
'indicatif': True
}
},
'pagination': {
'limite': 20
},
'options': {
'champ_tri': 'score_pertinence',
'ordre_tri': 'desc',
'champs': ['cadastre_id', 'superficie', 'score_pertinence']
}
}
response = requests.post(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
json=data,
headers={'Authorization': f'Bearer {api_key}'}
)
parcelles = response.json()
# Afficher les résultats triés par score
for p in parcelles:
print(f"Score: {p['score_pertinence']}/100 - {p['cadastre_id']} ({p['superficie']} m²)")
Structure de la requête POST
1. Section filtres
Tous vos critères de recherche avec mode strict ou indicatif.
{
"filtres": {
"code_municipalite": {
"value": "75056"
// Filtre géographique (STRICT uniquement, pas de champ indicatif)
},
"superficie": {
"min": 300,
"max": 800,
"indicatif": true // Mode scoring
}
}
}
2. Section pagination
{
"pagination": {
"limite": 20, // Nombre de résultats (max 50)
"curseur": "" // Curseur de pagination
}
}
3. Section options
{
"options": {
"format": "json", // json ou geojson
"geometrie": "centre", // centre, contour, bbox
"champs": [ // Champs à retourner
"cadastre_id",
"superficie",
"score_pertinence" // ⭐ Score de pertinence
],
"champ_tri": "score_pertinence", // Trier par score
"ordre_tri": "desc" // Descendant (meilleurs en premier)
}
}
Types de filtres avec scoring
Filtres de plage (FiltreRange)
Pour les valeurs min/max :
{
superficie: {
min: 300,
max: 800,
indicatif: true // Mode scoring
},
annee_construction: {
min: 1990,
max: 2020,
indicatif: false // Mode strict
}
}
Champs supportés :
superficie,jardin,emprise_sol,surface_habitablealtitude,hauteurannee_constructionpiscine_surfacedpe_date_reception,dpe_date_etablissementelec_tertiaire,elec_residentielle,gaz_tertiaire,gaz_residentielledvf_prix,dvf_dateestimation,estimation_ppm
Filtres à valeurs multiples (FiltreSimpleMultiple)
Pour sélectionner plusieurs valeurs :
{
dpe_energie: {
value: 'A,B,C', // Plusieurs étiquettes
indicatif: true // Mode scoring
},
bati_type: {
value: '1,3,5', // Plusieurs types de bâti
indicatif: false // Mode strict
}
}
Champs supportés :
bati_type(0-17)dpe_energie,dpe_ges(A-G)etages,mitoyen,batiment_dur,batiment_legerforme_piscine(0-4)dvf_code_type_bienpermis_type,permis_etat,permis_nature,permis_cat_demplu_zone,plu_zone_typerisque_argile,risque_radon(1-3)
Filtres booléens (FiltreBoolean)
Pour les valeurs true/false :
{
arpente: {
value: true,
indicatif: true // Mode scoring
},
piscine: {
value: true,
indicatif: false // Mode strict
}
}
Champs supportés :
arpente,isole,piscine,constructionpersonne_morale_presente,opportunite
Filtres stricts uniquement
Certains filtres ne supportent QUE le mode strict (pas de scoring) :
{
code_postal: {
value: '75008'
// Pas de champ "indicatif" - toujours strict
},
dvf_existe: {
value: true
// Pas de champ "indicatif" - toujours strict
}
}
Filtres géographiques (stricts uniquement) :
lat,lon,code_departement,code_municipalite,code_postal,code_iris,code_section
Cas d'usage avancés
1. Recherche de maison idéale avec scoring
- JavaScript
- PHP
- Python
async function rechercherMaisonIdeale() {
/**
* Rechercher une maison avec critères obligatoires et préférences
*/
const apiKey = process.env.INFOPARCELLE_API_KEY;
const data = {
filtres: {
// STRICT : Contraintes obligatoires
code_postal: {
value: '69000,69001,69002,69003' // Localisation stricte
},
bati_type: {
value: '1,2,3,4,5,6', // Maisons uniquement
indicatif: false // STRICT
},
piscine: {
value: true,
indicatif: false // STRICT : Doit avoir une piscine
},
// INDICATIF : Préférences (scoring)
superficie: {
min: 400,
max: 800,
indicatif: true // Idéal 400-800m², mais accepte autres
},
surface_habitable: {
min: 150,
max: 300,
indicatif: true // Préférence 150-300m²
},
annee_construction: {
min: 2000,
max: 2023,
indicatif: true // Préférence construction récente
},
dpe_energie: {
value: 'A,B,C',
indicatif: true // Préférence bon DPE
},
jardin: {
min: 100,
indicatif: true // Préférence jardin > 100m²
}
},
pagination: {
limite: 30
},
options: {
champ_tri: 'score_pertinence',
ordre_tri: 'desc',
champs: [
'cadastre_id',
'superficie',
'surface_habitable',
'annee_construction',
'dpes',
'score_pertinence'
]
}
};
const response = await fetch(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}
);
const parcelles = await response.json();
// Analyser les résultats
console.log(`${parcelles.length} maisons trouvées\n`);
parcelles.slice(0, 10).forEach((p, i) => {
const dpe = p.dpes?.[0];
console.log(`${i + 1}. Score: ${p.score_pertinence.toFixed(1)}/100`);
console.log(` ${p.cadastre_id}`);
console.log(` Superficie: ${p.superficie} m²`);
console.log(` Habitable: ${p.surface_habitable || 'N/A'} m²`);
console.log(` Construction: ${p.annee_construction || 'N/A'}`);
console.log(` DPE: ${dpe?.etiquette_dpe || 'N/A'}\n`);
});
return parcelles;
}
<?php
function rechercher_maison_ideale($api_key) {
/**
* Rechercher une maison avec critères obligatoires et préférences
*/
$data = [
'filtres' => [
// STRICT : Contraintes obligatoires
'code_postal' => [
'value' => '69000,69001,69002,69003' // Localisation stricte
],
'bati_type' => [
'value' => '1,2,3,4,5,6', // Maisons uniquement
'indicatif' => false // STRICT
],
'piscine' => [
'value' => true,
'indicatif' => false // STRICT : Doit avoir une piscine
],
// INDICATIF : Préférences (scoring)
'superficie' => [
'min' => 400,
'max' => 800,
'indicatif' => true // Idéal 400-800m², mais accepte autres
],
'surface_habitable' => [
'min' => 150,
'max' => 300,
'indicatif' => true // Préférence 150-300m²
],
'annee_construction' => [
'min' => 2000,
'max' => 2023,
'indicatif' => true // Préférence construction récente
],
'dpe_energie' => [
'value' => 'A,B,C',
'indicatif' => true // Préférence bon DPE
],
'jardin' => [
'min' => 100,
'indicatif' => true // Préférence jardin > 100m²
]
],
'pagination' => [
'limite' => 30
],
'options' => [
'champ_tri' => 'score_pertinence',
'ordre_tri' => 'desc',
'champs' => [
'cadastre_id',
'superficie',
'surface_habitable',
'annee_construction',
'dpes',
'score_pertinence'
]
]
];
$ch = curl_init('https://app.infoparcelle.fr/api/v1/parcelles/recherche');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $api_key",
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$parcelles = json_decode($response, true);
// Analyser les résultats
echo count($parcelles) . " maisons trouvées\n\n";
foreach (array_slice($parcelles, 0, 10) as $i => $p) {
$dpe = $p['dpes'][0] ?? null;
echo ($i + 1) . ". Score: " . round($p['score_pertinence'], 1) . "/100\n";
echo " {$p['cadastre_id']}\n";
echo " Superficie: {$p['superficie']} m²\n";
echo " Habitable: " . ($p['surface_habitable'] ?? 'N/A') . " m²\n";
echo " Construction: " . ($p['annee_construction'] ?? 'N/A') . "\n";
echo " DPE: " . ($dpe['etiquette_dpe'] ?? 'N/A') . "\n\n";
}
return $parcelles;
}
?>
import os
import requests
def rechercher_maison_ideale():
"""
Rechercher une maison avec critères obligatoires et préférences
"""
api_key = os.getenv('INFOPARCELLE_API_KEY')
data = {
'filtres': {
# STRICT : Contraintes obligatoires
'code_postal': {
'value': '69000,69001,69002,69003' # Localisation stricte
},
'bati_type': {
'value': '1,2,3,4,5,6', # Maisons uniquement
'indicatif': False # STRICT
},
'piscine': {
'value': True,
'indicatif': False # STRICT : Doit avoir une piscine
},
# INDICATIF : Préférences (scoring)
'superficie': {
'min': 400,
'max': 800,
'indicatif': True # Idéal 400-800m², mais accepte autres
},
'surface_habitable': {
'min': 150,
'max': 300,
'indicatif': True # Préférence 150-300m²
},
'annee_construction': {
'min': 2000,
'max': 2023,
'indicatif': True # Préférence construction récente
},
'dpe_energie': {
'value': 'A,B,C',
'indicatif': True # Préférence bon DPE
},
'jardin': {
'min': 100,
'indicatif': True # Préférence jardin > 100m²
}
},
'pagination': {
'limite': 30
},
'options': {
'champ_tri': 'score_pertinence',
'ordre_tri': 'desc',
'champs': [
'cadastre_id',
'superficie',
'surface_habitable',
'annee_construction',
'dpes',
'score_pertinence'
]
}
}
response = requests.post(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
json=data,
headers={'Authorization': f'Bearer {api_key}'}
)
parcelles = response.json()
# Analyser les résultats
print(f"{len(parcelles)} maisons trouvées\n")
for i, p in enumerate(parcelles[:10], 1):
dpe = p.get('dpes', [{}])[0]
print(f"{i}. Score: {p['score_pertinence']:.1f}/100")
print(f" {p['cadastre_id']}")
print(f" Superficie: {p['superficie']} m²")
print(f" Habitable: {p.get('surface_habitable', 'N/A')} m²")
print(f" Construction: {p.get('annee_construction', 'N/A')}")
print(f" DPE: {dpe.get('etiquette_dpe', 'N/A')}\n")
return parcelles
2. Recherche d'opportunité d'investissement
- JavaScript
- PHP
- Python
async function rechercherOpportunitesInvestissement(codePostal) {
/**
* Recherche des opportunités d'investissement avec scoring
*/
const apiKey = process.env.INFOPARCELLE_API_KEY;
const data = {
filtres: {
// STRICT : Localisation et type
code_postal: {
value: codePostal
},
bati_type: {
value: '7,8,9,10,11,12', // Appartements
indicatif: false // STRICT
},
// INDICATIF : Opportunités (scoring)
dpe_energie: {
value: 'F,G', // Passoires thermiques
indicatif: true // Préférence
},
annee_construction: {
max: 1980, // Vieux bâtiments
indicatif: true // Préférence
},
dvf_prix: {
max: 300000, // Prix abordable
indicatif: true // Préférence
},
surface_habitable: {
min: 50,
max: 100,
indicatif: true // Taille idéale
}
},
pagination: {
limite: 50
},
options: {
champ_tri: 'score_pertinence',
ordre_tri: 'desc',
champs: [
'cadastre_id',
'superficie',
'surface_habitable',
'annee_construction',
'dpes',
'dvfs',
'score_pertinence'
]
}
};
const response = await fetch(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}
);
const parcelles = await response.json();
// Analyser le potentiel
const opportunites = [];
for (const p of parcelles) {
const dpe = p.dpes?.[0] || {};
const dvf = p.dvfs?.[0] || {};
// Calculer le potentiel de rénovation
if (['F', 'G'].includes(dpe.etiquette_dpe)) {
const economieEnergie = (dpe.cout_total || 0) * 0.6; // 60% d'économie estimée
opportunites.push({
cadastre_id: p.cadastre_id,
score: p.score_pertinence,
prix_achat: dvf.valeur_fonciere,
annee: p.annee_construction,
dpe: dpe.etiquette_dpe,
economie_annuelle: Math.round(economieEnergie),
potentiel: p.score_pertinence > 80 ? 'ÉLEVÉ' : 'MOYEN'
});
}
}
return opportunites.sort((a, b) => b.score - a.score);
}
// Utilisation
const opportunites = await rechercherOpportunitesInvestissement('75008');
console.log('Top 10 opportunités trouvées:\n');
opportunites.slice(0, 10).forEach((opp, i) => {
console.log(`${i + 1}. Score: ${opp.score.toFixed(1)}/100 - Potentiel: ${opp.potentiel}`);
console.log(` ${opp.cadastre_id}`);
console.log(` Prix: ${opp.prix_achat?.toLocaleString()} € - DPE: ${opp.dpe}`);
console.log(` Économie énergie: ${opp.economie_annuelle} €/an\n`);
});
<?php
function rechercher_opportunites_investissement($code_postal, $api_key) {
/**
* Recherche des opportunités d'investissement avec scoring
*/
$data = [
'filtres' => [
// STRICT : Localisation et type
'code_postal' => [
'value' => $code_postal
],
'bati_type' => [
'value' => '7,8,9,10,11,12', // Appartements
'indicatif' => false // STRICT
],
// INDICATIF : Opportunités (scoring)
'dpe_energie' => [
'value' => 'F,G', // Passoires thermiques
'indicatif' => true // Préférence
],
'annee_construction' => [
'max' => 1980, // Vieux bâtiments
'indicatif' => true // Préférence
],
'dvf_prix' => [
'max' => 300000, // Prix abordable
'indicatif' => true // Préférence
],
'surface_habitable' => [
'min' => 50,
'max' => 100,
'indicatif' => true // Taille idéale
]
],
'pagination' => [
'limite' => 50
],
'options' => [
'champ_tri' => 'score_pertinence',
'ordre_tri' => 'desc',
'champs' => [
'cadastre_id',
'superficie',
'surface_habitable',
'annee_construction',
'dpes',
'dvfs',
'score_pertinence'
]
]
];
$ch = curl_init('https://app.infoparcelle.fr/api/v1/parcelles/recherche');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $api_key",
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$parcelles = json_decode($response, true);
// Analyser le potentiel
$opportunites = [];
foreach ($parcelles as $p) {
$dpe = $p['dpes'][0] ?? [];
$dvf = $p['dvfs'][0] ?? [];
// Calculer le potentiel de rénovation
if (in_array($dpe['etiquette_dpe'] ?? '', ['F', 'G'])) {
$economie_energie = ($dpe['cout_total'] ?? 0) * 0.6; // 60% d'économie estimée
$opportunites[] = [
'cadastre_id' => $p['cadastre_id'],
'score' => $p['score_pertinence'],
'prix_achat' => $dvf['valeur_fonciere'] ?? null,
'annee' => $p['annee_construction'] ?? null,
'dpe' => $dpe['etiquette_dpe'] ?? null,
'economie_annuelle' => round($economie_energie),
'potentiel' => $p['score_pertinence'] > 80 ? 'ÉLEVÉ' : 'MOYEN'
];
}
}
usort($opportunites, fn($a, $b) => $b['score'] <=> $a['score']);
return $opportunites;
}
// Utilisation
$api_key = getenv('INFOPARCELLE_API_KEY');
$opportunites = rechercher_opportunites_investissement('75008', $api_key);
echo "Top 10 opportunités trouvées:\n\n";
foreach (array_slice($opportunites, 0, 10) as $i => $opp) {
echo ($i + 1) . ". Score: " . round($opp['score'], 1) . "/100 - Potentiel: {$opp['potentiel']}\n";
echo " {$opp['cadastre_id']}\n";
echo " Prix: " . number_format($opp['prix_achat'], 0, ',', ' ') . " € - DPE: {$opp['dpe']}\n";
echo " Économie énergie: {$opp['economie_annuelle']} €/an\n\n";
}
?>
import os
import requests
def rechercher_opportunites_investissement(code_postal):
"""
Recherche des opportunités d'investissement avec scoring
"""
api_key = os.getenv('INFOPARCELLE_API_KEY')
data = {
'filtres': {
# STRICT : Localisation et type
'code_postal': {
'value': code_postal
},
'bati_type': {
'value': '7,8,9,10,11,12', # Appartements
'indicatif': False # STRICT
},
# INDICATIF : Opportunités (scoring)
'dpe_energie': {
'value': 'F,G', # Passoires thermiques
'indicatif': True # Préférence
},
'annee_construction': {
'max': 1980, # Vieux bâtiments
'indicatif': True # Préférence
},
'dvf_prix': {
'max': 300000, # Prix abordable
'indicatif': True # Préférence
},
'surface_habitable': {
'min': 50,
'max': 100,
'indicatif': True # Taille idéale
}
},
'pagination': {
'limite': 50
},
'options': {
'champ_tri': 'score_pertinence',
'ordre_tri': 'desc',
'champs': [
'cadastre_id',
'superficie',
'surface_habitable',
'annee_construction',
'dpes',
'dvfs',
'score_pertinence'
]
}
}
response = requests.post(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
json=data,
headers={'Authorization': f'Bearer {api_key}'}
)
parcelles = response.json()
# Analyser le potentiel
opportunites = []
for p in parcelles:
dpe = p.get('dpes', [{}])[0]
dvf = p.get('dvfs', [{}])[0]
# Calculer le potentiel de rénovation
if dpe.get('etiquette_dpe') in ['F', 'G']:
economie_energie = dpe.get('cout_total', 0) * 0.6 # 60% d'économie estimée
opportunites.append({
'cadastre_id': p['cadastre_id'],
'score': p['score_pertinence'],
'prix_achat': dvf.get('valeur_fonciere'),
'annee': p.get('annee_construction'),
'dpe': dpe.get('etiquette_dpe'),
'economie_annuelle': round(economie_energie),
'potentiel': 'ÉLEVÉ' if p['score_pertinence'] > 80 else 'MOYEN'
})
return sorted(opportunites, key=lambda x: x['score'], reverse=True)
# Utilisation
opportunites = rechercher_opportunites_investissement('75008')
print(f"Top 10 opportunités trouvées:\n")
for i, opp in enumerate(opportunites[:10], 1):
print(f"{i}. Score: {opp['score']:.1f}/100 - Potentiel: {opp['potentiel']}")
print(f" {opp['cadastre_id']}")
print(f" Prix: {opp['prix_achat']:,} € - DPE: {opp['dpe']}")
print(f" Économie énergie: {opp['economie_annuelle']} €/an\n")
3. Scoring personnalisé avec pondération manuelle
- JavaScript
- PHP
- Python
// Créer son propre système de scoring en combinant le score API
async function rechercheAvecPonderationPersonnalisee(preferences) {
/**
* Recherche avec système de pondération personnalisé
*/
const apiKey = process.env.INFOPARCELLE_API_KEY;
const data = {
filtres: {
code_municipalite: {
value: preferences.commune
},
// Tous les critères en mode indicatif
superficie: {
min: preferences.superficie.min,
max: preferences.superficie.max,
indicatif: true
},
dpe_energie: {
value: preferences.dpe,
indicatif: true
},
annee_construction: {
min: preferences.annee.min,
max: preferences.annee.max,
indicatif: true
},
piscine: {
value: preferences.piscine,
indicatif: true
}
},
pagination: { limite: 50 },
options: {
champ_tri: 'score_pertinence',
ordre_tri: 'desc',
champs: [
'cadastre_id',
'superficie',
'dpes',
'annee_construction',
'detail',
'score_pertinence'
]
}
};
const response = await fetch(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}
);
const parcelles = await response.json();
// Pondération personnalisée
const poids = {
scoreApi: 0.4, // 40% du score de l'API
dpe: 0.3, // 30% pour le DPE
piscine: 0.2, // 20% pour la piscine
jardin: 0.1 // 10% pour le jardin
};
const parcellesAvecScorePerso = parcelles.map(p => {
let scorePerso = 0;
// Score de l'API (0-100)
scorePerso += (p.score_pertinence / 100) * poids.scoreApi * 100;
// Score DPE
const dpe = p.dpes?.[0];
const scoresDpe = { A: 100, B: 85, C: 70, D: 55, E: 40, F: 25, G: 10 };
const scoreDpe = scoresDpe[dpe?.etiquette_dpe] || 0;
scorePerso += (scoreDpe / 100) * poids.dpe * 100;
// Score piscine
const aPiscine = p.detail?.piscines?.nombre > 0;
scorePerso += (aPiscine ? 1 : 0) * poids.piscine * 100;
// Score jardin
const jardin = p.detail?.surfaces?.jardin || 0;
const scoreJardin = Math.min(jardin / 200, 1); // Max à 200m²
scorePerso += scoreJardin * poids.jardin * 100;
return {
...p,
score_personnalise: Math.round(scorePerso)
};
});
// Trier par score personnalisé
return parcellesAvecScorePerso.sort((a, b) =>
b.score_personnalise - a.score_personnalise
);
}
// Utilisation
const resultats = await rechercheAvecPonderationPersonnalisee({
commune: '69123',
superficie: { min: 300, max: 800 },
dpe: 'A,B,C',
annee: { min: 1990, max: 2023 },
piscine: true
});
console.log('Top 10 avec scoring personnalisé:\n');
resultats.slice(0, 10).forEach((p, i) => {
console.log(`${i + 1}. Score perso: ${p.score_personnalise}/100 (API: ${p.score_pertinence}/100)`);
console.log(` ${p.cadastre_id} - ${p.superficie} m²\n`);
});
<?php
function recherche_avec_ponderation_personnalisee($preferences, $api_key) {
/**
* Recherche avec système de pondération personnalisé
*/
$data = [
'filtres' => [
'code_municipalite' => [
'value' => $preferences['commune']
],
// Tous les critères en mode indicatif
'superficie' => [
'min' => $preferences['superficie']['min'],
'max' => $preferences['superficie']['max'],
'indicatif' => true
],
'dpe_energie' => [
'value' => $preferences['dpe'],
'indicatif' => true
],
'annee_construction' => [
'min' => $preferences['annee']['min'],
'max' => $preferences['annee']['max'],
'indicatif' => true
],
'piscine' => [
'value' => $preferences['piscine'],
'indicatif' => true
]
],
'pagination' => ['limite' => 50],
'options' => [
'champ_tri' => 'score_pertinence',
'ordre_tri' => 'desc',
'champs' => [
'cadastre_id',
'superficie',
'dpes',
'annee_construction',
'detail',
'score_pertinence'
]
]
];
$ch = curl_init('https://app.infoparcelle.fr/api/v1/parcelles/recherche');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $api_key",
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$parcelles = json_decode($response, true);
// Pondération personnalisée
$poids = [
'score_api' => 0.4, // 40% du score de l'API
'dpe' => 0.3, // 30% pour le DPE
'piscine' => 0.2, // 20% pour la piscine
'jardin' => 0.1 // 10% pour le jardin
];
$parcelles_avec_score_perso = array_map(function($p) use ($poids) {
$score_perso = 0;
// Score de l'API (0-100)
$score_perso += ($p['score_pertinence'] / 100) * $poids['score_api'] * 100;
// Score DPE
$dpe = $p['dpes'][0] ?? null;
$scores_dpe = ['A' => 100, 'B' => 85, 'C' => 70, 'D' => 55, 'E' => 40, 'F' => 25, 'G' => 10];
$score_dpe = $scores_dpe[$dpe['etiquette_dpe'] ?? ''] ?? 0;
$score_perso += ($score_dpe / 100) * $poids['dpe'] * 100;
// Score piscine
$a_piscine = ($p['detail']['piscines']['nombre'] ?? 0) > 0;
$score_perso += ($a_piscine ? 1 : 0) * $poids['piscine'] * 100;
// Score jardin
$jardin = $p['detail']['surfaces']['jardin'] ?? 0;
$score_jardin = min($jardin / 200, 1); // Max à 200m²
$score_perso += $score_jardin * $poids['jardin'] * 100;
$p['score_personnalise'] = round($score_perso);
return $p;
}, $parcelles);
// Trier par score personnalisé
usort($parcelles_avec_score_perso, fn($a, $b) => $b['score_personnalise'] <=> $a['score_personnalise']);
return $parcelles_avec_score_perso;
}
// Utilisation
$api_key = getenv('INFOPARCELLE_API_KEY');
$resultats = recherche_avec_ponderation_personnalisee([
'commune' => '69123',
'superficie' => ['min' => 300, 'max' => 800],
'dpe' => 'A,B,C',
'annee' => ['min' => 1990, 'max' => 2023],
'piscine' => true
], $api_key);
echo "Top 10 avec scoring personnalisé:\n\n";
foreach (array_slice($resultats, 0, 10) as $i => $p) {
echo ($i + 1) . ". Score perso: {$p['score_personnalise']}/100 (API: {$p['score_pertinence']}/100)\n";
echo " {$p['cadastre_id']} - {$p['superficie']} m²\n\n";
}
?>
import os
import requests
def recherche_avec_ponderation_personnalisee(preferences):
"""
Recherche avec système de pondération personnalisé
"""
api_key = os.getenv('INFOPARCELLE_API_KEY')
data = {
'filtres': {
'code_municipalite': {
'value': preferences['commune']
},
# Tous les critères en mode indicatif
'superficie': {
'min': preferences['superficie']['min'],
'max': preferences['superficie']['max'],
'indicatif': True
},
'dpe_energie': {
'value': preferences['dpe'],
'indicatif': True
},
'annee_construction': {
'min': preferences['annee']['min'],
'max': preferences['annee']['max'],
'indicatif': True
},
'piscine': {
'value': preferences['piscine'],
'indicatif': True
}
},
'pagination': {'limite': 50},
'options': {
'champ_tri': 'score_pertinence',
'ordre_tri': 'desc',
'champs': [
'cadastre_id',
'superficie',
'dpes',
'annee_construction',
'detail',
'score_pertinence'
]
}
}
response = requests.post(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
json=data,
headers={'Authorization': f'Bearer {api_key}'}
)
parcelles = response.json()
# Pondération personnalisée
poids = {
'score_api': 0.4, # 40% du score de l'API
'dpe': 0.3, # 30% pour le DPE
'piscine': 0.2, # 20% pour la piscine
'jardin': 0.1 # 10% pour le jardin
}
parcelles_avec_score_perso = []
for p in parcelles:
score_perso = 0
# Score de l'API (0-100)
score_perso += (p['score_pertinence'] / 100) * poids['score_api'] * 100
# Score DPE
dpe = p.get('dpes', [{}])[0]
scores_dpe = {'A': 100, 'B': 85, 'C': 70, 'D': 55, 'E': 40, 'F': 25, 'G': 10}
score_dpe = scores_dpe.get(dpe.get('etiquette_dpe'), 0)
score_perso += (score_dpe / 100) * poids['dpe'] * 100
# Score piscine
a_piscine = p.get('detail', {}).get('piscines', {}).get('nombre', 0) > 0
score_perso += (1 if a_piscine else 0) * poids['piscine'] * 100
# Score jardin
jardin = p.get('detail', {}).get('surfaces', {}).get('jardin', 0)
score_jardin = min(jardin / 200, 1) # Max à 200m²
score_perso += score_jardin * poids['jardin'] * 100
p['score_personnalise'] = round(score_perso)
parcelles_avec_score_perso.append(p)
# Trier par score personnalisé
return sorted(parcelles_avec_score_perso, key=lambda x: x['score_personnalise'], reverse=True)
# Utilisation
resultats = recherche_avec_ponderation_personnalisee({
'commune': '69123',
'superficie': {'min': 300, 'max': 800},
'dpe': 'A,B,C',
'annee': {'min': 1990, 'max': 2023},
'piscine': True
})
print("Top 10 avec scoring personnalisé:\n")
for i, p in enumerate(resultats[:10], 1):
print(f"{i}. Score perso: {p['score_personnalise']}/100 (API: {p['score_pertinence']}/100)")
print(f" {p['cadastre_id']} - {p['superficie']} m²\n")
4. Comparaison de zones avec scoring
- JavaScript
- PHP
- Python
async function comparerZonesAvecScoring(codesPostaux, criteres) {
/**
* Comparer plusieurs zones géographiques avec scoring
*/
const apiKey = process.env.INFOPARCELLE_API_KEY;
const resultatsParZone = {};
for (const cp of codesPostaux) {
const data = {
filtres: {
code_postal: { value: cp },
superficie: {
min: criteres.superficieMin,
max: criteres.superficieMax,
indicatif: true
},
dpe_energie: {
value: criteres.dpe,
indicatif: true
}
},
pagination: { limite: 30 },
options: {
champ_tri: 'score_pertinence',
ordre_tri: 'desc',
champs: ['cadastre_id', 'superficie', 'score_pertinence']
}
};
const response = await fetch(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}
);
const parcelles = await response.json();
// Calculer les statistiques
const scores = parcelles.map(p => p.score_pertinence);
resultatsParZone[cp] = {
total: parcelles.length,
scoreMoyen: scores.reduce((a, b) => a + b, 0) / scores.length,
scoreMax: Math.max(...scores),
scoreMin: Math.min(...scores),
topParcelles: parcelles.slice(0, 5)
};
}
return resultatsParZone;
}
// Utilisation
const comparaison = await comparerZonesAvecScoring(
['75008', '75016', '75017'],
{
superficieMin: 300,
superficieMax: 800,
dpe: 'A,B,C'
}
);
for (const [cp, stats] of Object.entries(comparaison)) {
console.log(`Code postal ${cp}:`);
console.log(` Total: ${stats.total} parcelles`);
console.log(` Score moyen: ${stats.scoreMoyen.toFixed(1)}/100`);
console.log(` Meilleur score: ${stats.scoreMax}/100\n`);
}
<?php
function comparer_zones_avec_scoring($codes_postaux, $criteres, $api_key) {
/**
* Comparer plusieurs zones géographiques avec scoring
*/
$resultats_par_zone = [];
foreach ($codes_postaux as $cp) {
$data = [
'filtres' => [
'code_postal' => ['value' => $cp],
'superficie' => [
'min' => $criteres['superficie_min'],
'max' => $criteres['superficie_max'],
'indicatif' => true
],
'dpe_energie' => [
'value' => $criteres['dpe'],
'indicatif' => true
]
],
'pagination' => ['limite' => 30],
'options' => [
'champ_tri' => 'score_pertinence',
'ordre_tri' => 'desc',
'champs' => ['cadastre_id', 'superficie', 'score_pertinence']
]
];
$ch = curl_init('https://app.infoparcelle.fr/api/v1/parcelles/recherche');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $api_key",
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$parcelles = json_decode($response, true);
// Calculer les statistiques
$scores = array_map(fn($p) => $p['score_pertinence'], $parcelles);
$resultats_par_zone[$cp] = [
'total' => count($parcelles),
'score_moyen' => array_sum($scores) / count($scores),
'score_max' => max($scores),
'score_min' => min($scores),
'top_parcelles' => array_slice($parcelles, 0, 5)
];
}
return $resultats_par_zone;
}
// Utilisation
$api_key = getenv('INFOPARCELLE_API_KEY');
$comparaison = comparer_zones_avec_scoring(
['75008', '75016', '75017'],
[
'superficie_min' => 300,
'superficie_max' => 800,
'dpe' => 'A,B,C'
],
$api_key
);
foreach ($comparaison as $cp => $stats) {
echo "Code postal $cp:\n";
echo " Total: {$stats['total']} parcelles\n";
echo " Score moyen: " . round($stats['score_moyen'], 1) . "/100\n";
echo " Meilleur score: {$stats['score_max']}/100\n\n";
}
?>
import os
import requests
def comparer_zones_avec_scoring(codes_postaux, criteres):
"""
Comparer plusieurs zones géographiques avec scoring
"""
api_key = os.getenv('INFOPARCELLE_API_KEY')
resultats_par_zone = {}
for cp in codes_postaux:
data = {
'filtres': {
'code_postal': {'value': cp},
'superficie': {
'min': criteres['superficie_min'],
'max': criteres['superficie_max'],
'indicatif': True
},
'dpe_energie': {
'value': criteres['dpe'],
'indicatif': True
}
},
'pagination': {'limite': 30},
'options': {
'champ_tri': 'score_pertinence',
'ordre_tri': 'desc',
'champs': ['cadastre_id', 'superficie', 'score_pertinence']
}
}
response = requests.post(
'https://app.infoparcelle.fr/api/v1/parcelles/recherche',
json=data,
headers={'Authorization': f'Bearer {api_key}'}
)
parcelles = response.json()
# Calculer les statistiques
scores = [p['score_pertinence'] for p in parcelles]
resultats_par_zone[cp] = {
'total': len(parcelles),
'score_moyen': sum(scores) / len(scores),
'score_max': max(scores),
'score_min': min(scores),
'top_parcelles': parcelles[:5]
}
return resultats_par_zone
# Utilisation
comparaison = comparer_zones_avec_scoring(
['75008', '75016', '75017'],
{
'superficie_min': 300,
'superficie_max': 800,
'dpe': 'A,B,C'
}
)
for cp, stats in comparaison.items():
print(f"Code postal {cp}:")
print(f" Total: {stats['total']} parcelles")
print(f" Score moyen: {stats['score_moyen']:.1f}/100")
print(f" Meilleur score: {stats['score_max']}/100\n")
Interprétation du score
Plages de score
- 90-100 : Correspondance excellente (tous les critères indicatifs respectés)
- 75-89 : Très bonne correspondance (la plupart des critères respectés)
- 60-74 : Bonne correspondance (critères principaux respectés)
- 40-59 : Correspondance moyenne (certains critères non respectés)
- 0-39 : Faible correspondance (peu de critères respectés)
Conseils d'utilisation
-
Seuil minimal : Filtrer les résultats avec
score_pertinence >= 60pour ne garder que les bonnes correspondances -
Analyse du top : Se concentrer sur les 10-20 premiers résultats (scores les plus élevés)
-
Ajustement des critères : Si tous les scores sont faibles, assouplir certains critères indicatifs
Bonnes pratiques
✅ À faire
- Combiner strict et indicatif : Filtres géographiques en strict, préférences en indicatif
- Trier par score : Utiliser
champ_tri: "score_pertinence"pour avoir les meilleurs résultats en premier - Limiter les résultats : Commencer avec
limite: 20-30pour tester - Analyser les scores : Examiner la distribution des scores pour ajuster les critères
- Créer des profils : Sauvegarder vos combinaisons de critères efficaces
❌ À éviter
- ❌ Trop de critères indicatifs : Limite à 5-7 critères pour une bonne pertinence
- ❌ Ignorer les scores faibles : Un score < 40 signifie une mauvaise correspondance
- ❌ Oublier le filtre géographique : TOUJOURS requis (au moins un)
- ❌ Utiliser uniquement le mode strict : Vous perdez l'avantage du scoring
- ❌ Ne pas paginer : Traiter les résultats par lots de 20-50
Limites et contraintes
- Au moins UN filtre géographique requis (code_postal, code_municipalite, etc.)
- Maximum 50 résultats par requête (utilisez la pagination)
- Filtres géographiques STRICT uniquement (pas de mode indicatif)
- Score calculé automatiquement (pas de pondération manuelle via l'API)
- Rate limit : 1200 requêtes/minute
Performances
- Temps de réponse moyen : < 300ms (légèrement plus lent que GET en raison du calcul de score)
- Cache côté serveur : 15 minutes
- Complexité de calcul : Proportionnelle au nombre de critères indicatifs
Voir aussi
- Rechercher des parcelles (GET) - Recherche simple
- Fiche parcelle complète - Détails et analyse
- Référence API - Documentation technique complète de l'API
Le système de scoring vous permet de créer des recherches flexibles et intelligentes. Combinez des contraintes obligatoires (mode strict) avec des préférences (mode indicatif) pour trouver les parcelles les plus pertinentes !