Point Enrichment
This use case shows how to enrich individual or batch locations with geospatial layer data.
Using Python?
The Python SDK wraps enrichment endpoints in a typed client — client.enrichment.enrich_single(...) and client.enrichment.enrich_batch(...).
Scenario
You have a list of addresses or coordinates and need to:
- Enrich each point with geospatial layer information (flood risk, demographics, etc.)
- Retrieve specific attributes or aggregate metrics
- Process single points or large batches efficiently
Single Point Enrichment
Enrich a single location with layer data:
curl -X GET "https://graph.quarticle.ro/graph/featureinfo/risk-lookup/api/v1/bfi/single" \
-H "Authorization: YOUR_API_KEY" \
--data-urlencode "lat=40.7128" \
--data-urlencode "lng=-74.0060" \
--data-urlencode "layers=flood_risk,demographic_density,environmental_quality" \
--data-urlencode "operation=enhance"
Parameters:
lat- Latitude (WGS84)lng- Longitude (WGS84)layers- Comma-separated layer namesoperation-enhanceto get attributes,countto count features
Response:
{
"location": {"lat": 40.7128, "lng": -74.0060},
"layers": {
"flood_risk": {
"risk_level": "medium",
"return_period": "100_year",
"depth_cm": 45
},
"demographic_density": {
"population": 42500,
"density_per_sq_km": 15800
},
"environmental_quality": {
"air_quality_index": 72,
"water_quality_score": 68
}
}
}
Batch Point Enrichment
Enrich multiple points in a single request:
{
"points": [
{"id": "prop_001", "lat": 40.7128, "lng": -74.0060},
{"id": "prop_002", "lat": 40.7250, "lng": -74.0100},
{"id": "prop_003", "lat": 40.7400, "lng": -74.0050}
],
"layers": ["flood_risk", "seismic_risk", "demographic_density"],
"operation": "enhance"
}
Response:
[
{
"id": "prop_001",
"location": {"lat": 40.7128, "lng": -74.0060},
"enrichment": {
"flood_risk": {...},
"seismic_risk": {...},
"demographic_density": {...}
}
},
{
"id": "prop_002",
"location": {"lat": 40.7250, "lng": -74.0100},
"enrichment": {...}
},
{
"id": "prop_003",
"location": {"lat": 40.7400, "lng": -74.0050},
"enrichment": {...}
}
]
Code Examples
Single Point (JavaScript)
async function enrichSinglePoint(lat, lng, layers) {
const apiKey = process.env.QARTA_API_KEY;
const params = new URLSearchParams({
lat: lat,
lng: lng,
layers: layers.join(','),
operation: 'enhance'
});
const response = await fetch(
`https://graph.quarticle.ro/graph/featureinfo/risk-lookup/api/v1/bfi/single?${params}`,
{
method: 'GET',
headers: {
'Authorization': `${apiKey}`
}
}
);
const enriched = await response.json();
console.log(JSON.stringify(enriched, null, 2));
return enriched;
}
// Usage
const result = await enrichSinglePoint(
40.7128,
-74.0060,
['flood_risk', 'demographic_density', 'environmental_quality']
);
Batch Enrichment (JavaScript)
async function enrichBatchPoints(properties, layers) {
const apiKey = process.env.QARTA_API_KEY;
const request = {
points: properties.map(p => ({
id: p.id,
lat: p.latitude,
lng: p.longitude
})),
layers: layers,
operation: 'enhance'
};
const response = await fetch(
'https://graph.quarticle.ro/graph/featureinfo/enrichment/api/v1/bfi/batch',
{
method: 'POST',
headers: {
'Authorization': `${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}
);
const enriched = await response.json();
// Process results
enriched.forEach(item => {
console.log(`${item.id}: Enriched with ${Object.keys(item.enrichment).length} layers`);
});
return enriched;
}
// Usage
const properties = [
{ id: 'prop_001', latitude: 40.7128, longitude: -74.0060 },
{ id: 'prop_002', latitude: 40.7250, longitude: -74.0100 },
{ id: 'prop_003', latitude: 40.7400, longitude: -74.0050 }
];
const enriched = await enrichBatchPoints(
properties,
['flood_risk', 'seismic_risk', 'demographic_density']
);
Batch Enrichment (Python)
import requests
import json
import csv
def enrich_properties_from_csv(csv_file, output_file):
api_key = os.getenv('QARTA_API_KEY')
# Read CSV
properties = []
with open(csv_file, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
properties.append({
'id': row['property_id'],
'latitude': float(row['lat']),
'longitude': float(row['lon'])
})
# Batch enrich
request_body = {
'points': [
{'id': p['id'], 'lat': p['latitude'], 'lng': p['longitude']}
for p in properties
],
'layers': ['flood_risk', 'demographic_density'],
'operation': 'enhance'
}
response = requests.post(
'https://graph.quarticle.ro/graph/featureinfo/enrichment/api/v1/bfi/batch',
headers={
'Authorization': f'{api_key}',
'Content-Type': 'application/json'
},
json=request_body
)
enriched_data = response.json()
# Write results to file
with open(output_file, 'w') as f:
json.dump(enriched_data, f, indent=2)
print(f'Enriched {len(enriched_data)} properties')
print(f'Results saved to {output_file}')
# Usage
enrich_properties_from_csv('properties.csv', 'enriched_properties.json')
Count Operation
Instead of enrichment, count features in layers:
curl -X GET "https://graph.quarticle.ro/graph/featureinfo/risk-lookup/api/v1/bfi/single" \
-H "Authorization: YOUR_API_KEY" \
--data-urlencode "lat=40.7128" \
--data-urlencode "lng=-74.0060" \
--data-urlencode "layers=flood_zones,environmental_areas" \
--data-urlencode "operation=count"
Response:
{
"location": {"lat": 40.7128, "lng": -74.0060},
"layers": {
"flood_zones": {
"count": 3,
"features": [...]
},
"environmental_areas": {
"count": 1,
"features": [...]
}
}
}
Large Batch Processing
For thousands of points, process in smaller batches:
async function enrichLargeDataset(properties, batchSize = 1000) {
const apiKey = process.env.QARTA_API_KEY;
const results = [];
for (let i = 0; i < properties.length; i += batchSize) {
const batch = properties.slice(i, i + batchSize);
console.log(`Processing batch ${Math.floor(i / batchSize) + 1}...`);
const request = {
points: batch.map(p => ({
id: p.id,
lat: p.lat,
lng: p.lng
})),
layers: ['flood_risk', 'demographic_density'],
operation: 'enhance'
};
const response = await fetch(
'https://graph.quarticle.ro/graph/featureinfo/enrichment/api/v1/bfi/batch',
{
method: 'POST',
headers: {
'Authorization': `${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}
);
const enriched = await response.json();
results.push(...enriched);
// Add delay between batches
await new Promise(resolve => setTimeout(resolve, 500));
}
return results;
}
const allProperties = [...]; // Your list of 10,000+ properties
const enriched = await enrichLargeDataset(allProperties, 1000);
Use Cases
- Property valuation - Incorporate risk/demographic data into pricing models
- Investment screening - Filter properties by enriched attributes
- Insurance risk assessment - Evaluate environmental and natural hazard risks
- Marketing analysis - Target properties in specific demographic areas
- Portfolio enhancement - Add context data to property records
- Due diligence - Evaluate multiple locations quickly
Error Handling
async function enrichWithErrorHandling(lat, lng, layers) {
try {
const params = new URLSearchParams({
lat, lng,
layers: layers.join(','),
operation: 'enhance'
});
const response = await fetch(
`https://graph.quarticle.ro/graph/featureinfo/risk-lookup/api/v1/bfi/single?${params}`,
{ headers: { 'Authorization': `${apiKey}` } }
);
if (response.status === 400) {
console.error('Invalid coordinates or layers');
return null;
}
if (response.status === 401) {
console.error('Authentication failed');
return null;
}
return await response.json();
} catch (error) {
console.error('Enrichment failed:', error);
return null;
}
}
Next Steps
- Risk Reporting Use Case - Generate risk assessment reports
- Portfolio Analysis Use Case - Analyze portfolio data
- Spatial Data Guide - Working with coordinates