Geofence Proximity
Discover nearby geofences and verify location containment for proximity-based features and validation workflows. Proximity detection identifies geofences near a location and determines point containment.
Use Cases
Applications requiring location-based intelligence:
- Navigation apps finding nearby parking or service areas
- Delivery systems validating addresses within service zones
- Security systems detecting proximity to restricted areas
- Field service locating work sites near technician positions
Example 1: Find Nearby Geofences
Locate geofences within a specified radius.
- cURL
- JavaScript
curl -X GET https://api.magiclane.net/api/v1/get_geofence_proximity_areas \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"p_location": [25.612211, 45.647781],
"p_limit_count": 10,
"p_distance_tolerance_m": 1000,
"p_keywords": ["parking", "warehouse"]
}'
const findNearbyGeofences = async (longitude, latitude, radiusMeters, filterKeywords = []) => {
const response = await fetch(
'https://api.magiclane.net/api/v1/get_geofence_proximity_areas',
{
method: 'GET',
headers: {
'Authorization': 'YOUR_API_KEY',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
p_location: [longitude, latitude],
p_limit_count: 10,
p_distance_tolerance_m: radiusMeters,
p_keywords: filterKeywords
})
}
);
const geofences = await response.json();
// Order by proximity
return geofences.sort((a, b) =>
Math.abs(a.distance_to_border) - Math.abs(b.distance_to_border)
);
};
// Find parking within 1km
const nearbyParking = await findNearbyGeofences(
25.612211,
45.647781,
1000,
['parking']
);
nearbyParking.forEach(zone => {
const distance = Math.abs(zone.distance_to_border);
const status = zone.contains_point ? 'inside' : 'outside';
console.log(`${zone.name}: ${distance.toFixed(0)}m (${status})`);
});
Response Example (code 200 OK)
[
{
"id": "employee_parking_lot",
"name": "Employee Parking Area",
"contains_point": false,
"distance_to_border": -415.75
},
{
"id": "parking_lot_area",
"name": "Employee Parking Zone (Circular)",
"contains_point": false,
"distance_to_border": -416.34
}
]
Understanding Distance Metrics
| Distance Value | Meaning | Interpretation |
|---|---|---|
| Negative (e.g., -415.75) | Outside geofence | Distance to nearest border in meters |
| Positive (e.g., +150.50) | Inside geofence | Distance from nearest border in meters |
| Zero (0) | On boundary | Point lies exactly on geofence edge |
Visual Example:
Outside zone: [-500m] --> [Border] --> [+200m] Inside zone
Point A Point B
Example 2: Validate Location Containment
Check if coordinates fall within specific geofences.
- cURL
- JavaScript
curl -X GET https://api.magiclane.net/api/v1/geofences_contain_locations \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"p_geofence_ids": [
"parking_lot_area",
"warehouse_safe_zone",
"employee_parking_lot"
],
"p_locations": [
[25.608396, 45.636208],
[25.628249, 45.653283],
[25.615265, 45.654491]
]
}'
const validateLocationContainment = async (geofenceIds, coordinatePairs) => {
const response = await fetch(
'https://api.magiclane.net/api/v1/geofences_contain_locations',
{
method: 'GET',
headers: {
'Authorization': 'YOUR_API_KEY',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
p_geofence_ids: geofenceIds,
p_locations: coordinatePairs
})
}
);
return response.json();
};
// Validate delivery addresses
const deliveryPoints = [
[25.608396, 45.636208], // Address 1
[25.628249, 45.653283], // Address 2
[25.615265, 45.654491] // Address 3
];
const serviceZones = ['downtown_delivery_zone', 'suburban_delivery_zone'];
const validation = await validateLocationContainment(serviceZones, deliveryPoints);
// Report invalid locations
validation.checked_geofences.forEach(zone => {
zone.locations.forEach(point => {
if (!point.inside) {
console.warn(`Address ${point.index} is outside ${zone.geofence_id} by ${point.distance_m}m`);
}
});
});
Response Example (code 200 OK)
{
"checked_geofences": [
{
"geofence_id": "parking_lot_area",
"locations": [
{ "index": 0, "inside": false, "distance_m": 642 },
{ "index": 1, "inside": false, "distance_m": 1546 },
{ "index": 2, "inside": false, "distance_m": 1178 }
]
}
]
}
Example 3: Parking Finder
Build a parking recommendation system.
- JavaScript
class ParkingFinder {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.magiclane.net/api/v1';
}
async recommendParking(userLon, userLat, maxDistanceMeters = 2000) {
const response = await fetch(
`${this.baseUrl}/get_geofence_proximity_areas`,
{
method: 'GET',
headers: {
'Authorization': this.apiKey,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
p_location: [userLon, userLat],
p_limit_count: 5,
p_distance_tolerance_m: maxDistanceMeters,
p_keywords: ['parking']
})
}
);
const parkingOptions = await response.json();
if (parkingOptions.length === 0) {
return {
success: false,
message: `No parking zones found within ${maxDistanceMeters}m`,
recommendations: []
};
}
const recommendations = parkingOptions.map(parking => {
const distanceAbs = Math.abs(parking.distance_to_border);
return {
name: parking.name,
id: parking.id,
distance_meters: Math.round(distanceAbs),
is_current_location: parking.contains_point,
walking_time_min: Math.ceil(distanceAbs / 80), // ~80m/min walking
guidance: parking.contains_point
? 'You are already in this parking area'
: `Walk ${Math.round(distanceAbs)}m to reach this parking`
};
});
// Sort by distance
recommendations.sort((a, b) => a.distance_meters - b.distance_meters);
return {
success: true,
nearest: recommendations[0],
recommendations: recommendations
};
}
}
// Usage example
const parkingFinder = new ParkingFinder('YOUR_API_KEY');
const result = await parkingFinder.recommendParking(25.612211, 45.647781);
if (result.success) {
console.log(`Nearest: ${result.nearest.name}`);
console.log(`Distance: ${result.nearest.distance_meters}m`);
console.log(`Walking time: ~${result.nearest.walking_time_min} minutes`);
}
Example 4: Proximity Alert System
Monitor distance to restricted zones using either specific geofence IDs or keywords.
- ID-Based Filtering
- Keyword-Based Filtering
class ProximityMonitorByIds {
constructor(apiKey, warningMeters = 500, dangerMeters = 100) {
this.apiKey = apiKey;
this.warningThreshold = warningMeters;
this.dangerThreshold = dangerMeters;
}
async checkRestrictedProximity(currentLon, currentLat, restrictedGeofenceIds) {
const response = await fetch(
'https://api.magiclane.net/api/v1/get_geofence_proximity_areas',
{
method: 'GET',
headers: {
'Authorization': this.apiKey,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
p_location: [currentLon, currentLat],
p_limit_count: 10,
p_distance_tolerance_m: this.warningThreshold,
p_keywords: [] // No keyword filtering, will filter by IDs below
})
}
);
const nearbyZones = await response.json();
// Filter to only the specific restricted geofence IDs we care about
const restrictedNearby = nearbyZones.filter(zone =>
restrictedGeofenceIds.includes(zone.id)
);
const alerts = [];
for (const zone of restrictedNearby) {
const dist = Math.abs(zone.distance_to_border);
if (zone.contains_point) {
alerts.push({
severity: 'CRITICAL',
zone_name: zone.name,
zone_id: zone.id,
message: 'BREACH: Inside restricted area',
distance_m: 0,
action: 'Evacuate immediately'
});
} else if (dist <= this.dangerThreshold) {
alerts.push({
severity: 'DANGER',
zone_name: zone.name,
zone_id: zone.id,
message: `Extremely close to restricted zone (${dist.toFixed(0)}m)`,
distance_m: Math.round(dist),
action: 'Change direction now'
});
} else if (dist <= this.warningThreshold) {
alerts.push({
severity: 'WARNING',
zone_name: zone.name,
zone_id: zone.id,
message: `Approaching restricted zone (${dist.toFixed(0)}m away)`,
distance_m: Math.round(dist),
action: 'Maintain awareness'
});
}
}
return {
is_safe: alerts.length === 0,
alert_count: alerts.length,
alerts: alerts.sort((a, b) => a.distance_m - b.distance_m)
};
}
}
// Usage with specific geofence IDs
const monitor = new ProximityMonitorByIds('YOUR_API_KEY', 500, 100);
const vehiclePosition = [25.612211, 45.647781];
// Array of specific geofence IDs to monitor
const restrictedGeofenceIds = [
'military_zone_alpha', // Geofence ID
'hazmat_storage_area_b', // Geofence ID
'restricted_airfield_zone' // Geofence ID
];
const status = await monitor.checkRestrictedProximity(
vehiclePosition[0],
vehiclePosition[1],
restrictedGeofenceIds
);
if (!status.is_safe) {
status.alerts.forEach(alert => {
console.log(`[${alert.severity}] ${alert.message}`);
console.log(`Zone: ${alert.zone_name} (ID: ${alert.zone_id})`);
console.log(`Action: ${alert.action}\n`);
});
}
class ProximityMonitorByKeywords {
constructor(apiKey, warningMeters = 500, dangerMeters = 100) {
this.apiKey = apiKey;
this.warningThreshold = warningMeters;
this.dangerThreshold = dangerMeters;
}
async checkRestrictedProximity(currentLon, currentLat, restrictedKeywords) {
const response = await fetch(
'https://api.magiclane.net/api/v1/get_geofence_proximity_areas',
{
method: 'GET',
headers: {
'Authorization': this.apiKey,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
p_location: [currentLon, currentLat],
p_limit_count: 10,
p_distance_tolerance_m: this.warningThreshold,
p_keywords: restrictedKeywords // Filter by keywords directly
})
}
);
const nearbyZones = await response.json();
// All returned zones match our keywords, no additional filtering needed
const alerts = [];
for (const zone of nearbyZones) {
const dist = Math.abs(zone.distance_to_border);
if (zone.contains_point) {
alerts.push({
severity: 'CRITICAL',
zone_name: zone.name,
zone_id: zone.id,
message: 'BREACH: Inside restricted area',
distance_m: 0,
action: 'Evacuate immediately'
});
} else if (dist <= this.dangerThreshold) {
alerts.push({
severity: 'DANGER',
zone_name: zone.name,
zone_id: zone.id,
message: `Extremely close to restricted zone (${dist.toFixed(0)}m)`,
distance_m: Math.round(dist),
action: 'Change direction now'
});
} else if (dist <= this.warningThreshold) {
alerts.push({
severity: 'WARNING',
zone_name: zone.name,
zone_id: zone.id,
message: `Approaching restricted zone (${dist.toFixed(0)}m away)`,
distance_m: Math.round(dist),
action: 'Maintain awareness'
});
}
}
return {
is_safe: alerts.length === 0,
alert_count: alerts.length,
alerts: alerts.sort((a, b) => a.distance_m - b.distance_m)
};
}
}
// Usage with keywords - much simpler and more maintainable!
const monitor = new ProximityMonitorByKeywords('YOUR_API_KEY', 500, 100);
const vehiclePosition = [25.612211, 45.647781];
// Array of keywords that identify restricted zones
const restrictedKeywords = [
'restricted',
'military',
'hazmat',
'no-entry'
];
const status = await monitor.checkRestrictedProximity(
vehiclePosition[0],
vehiclePosition[1],
restrictedKeywords
);
if (!status.is_safe) {
status.alerts.forEach(alert => {
console.log(`[${alert.severity}] ${alert.message}`);
console.log(`Zone: ${alert.zone_name} (ID: ${alert.zone_id})`);
console.log(`Action: ${alert.action}\n`);
});
}
When to Use Each Approach
| Approach | Best For | Advantages | Disadvantages |
|---|---|---|---|
| ID-Based | Fixed set of specific zones | Precise control, no false positives | Manual maintenance, doesn't scale |
| Keyword-Based | Dynamic zone types | Auto-includes new zones, scalable | Requires consistent keyword tagging |
Recommendation: Use keyword-based filtering for most use cases as it's simpler and automatically includes new geofences with matching keywords. Use ID-based filtering only when you need to monitor a fixed set of specific zones.
Common Use Cases
Delivery Address Validation
- JavaScript
async function isAddressInServiceArea(address, serviceZoneIds) {
const check = await validateLocationContainment(serviceZoneIds, [address]);
return check.checked_geofences.some(zone =>
zone.locations.some(loc => loc.inside)
);
}
Nearest Facility Finder
- JavaScript
async function findNearestFacility(userLocation, facilityType) {
const nearby = await findNearbyGeofences(
userLocation[0],
userLocation[1],
3000,
[facilityType]
);
return nearby.length > 0 ? nearby[0] : null;
}
Geofence Breach Detection
- JavaScript
async function detectUnauthorizedEntry(assetLocation, allowedZoneIds) {
const nearbyAll = await findNearbyGeofences(
assetLocation[0],
assetLocation[1],
100,
[]
);
return nearbyAll.filter(z =>
!allowedZoneIds.includes(z.id) && z.contains_point
);
}
Notes
- Use keyword filters to narrow geofences results
- Set reasonable distance tolerances
- Always check
contains_pointflag - Use absolute values for distance comparisons