location-ar-experience
Designs location-based augmented reality experiences with geospatial anchoring, GPS integration, and real-world interactive overlays.
What this skill does
# Location-Based AR Experience
This skill provides guidance for designing augmented reality experiences anchored to real-world locations, combining GPS, computer vision, and spatial computing.
## Core Competencies
- **Geospatial Anchoring**: GPS, geofencing, coordinate systems
- **Visual Positioning**: SLAM, image recognition, cloud anchors
- **Content Placement**: World-scale AR, occlusion, persistence
- **Mobile AR Platforms**: ARKit, ARCore, WebXR
## Location-Based AR Fundamentals
### AR Experience Types
```
┌─────────────────────────────────────────────────────────────────────┐
│ Location-Based AR Spectrum │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ GPS-Only Hybrid Vision-Based │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ ~10m │ │ ~1m │ │ ~1cm │ │
│ │accuracy │ │accuracy │ │accuracy │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ City-scale Building-scale Room-scale │
│ navigation experiences precision │
│ games POI overlays installations │
│ │
└─────────────────────────────────────────────────────────────────────┘
```
### Accuracy Requirements by Experience Type
| Experience | Required Accuracy | Positioning Method |
|------------|-------------------|-------------------|
| City navigation | 5-15 meters | GPS |
| POI discovery | 3-5 meters | GPS + Wi-Fi |
| Building entrance | 1-2 meters | GPS + Vision |
| Indoor navigation | 0.5-1 meter | Vision + beacons |
| Object placement | 1-10 cm | Pure visual SLAM |
## Geospatial Systems
### Coordinate Systems
```python
from dataclasses import dataclass
import math
@dataclass
class GeoCoordinate:
"""WGS84 coordinate"""
latitude: float # -90 to 90
longitude: float # -180 to 180
altitude: float = 0 # meters above sea level
def distance_to(self, other: 'GeoCoordinate') -> float:
"""Haversine distance in meters"""
R = 6371000 # Earth radius in meters
lat1, lat2 = math.radians(self.latitude), math.radians(other.latitude)
dlat = math.radians(other.latitude - self.latitude)
dlon = math.radians(other.longitude - self.longitude)
a = (math.sin(dlat/2)**2 +
math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return R * c
def bearing_to(self, other: 'GeoCoordinate') -> float:
"""Bearing in degrees (0-360)"""
lat1 = math.radians(self.latitude)
lat2 = math.radians(other.latitude)
dlon = math.radians(other.longitude - self.longitude)
x = math.sin(dlon) * math.cos(lat2)
y = (math.cos(lat1) * math.sin(lat2) -
math.sin(lat1) * math.cos(lat2) * math.cos(dlon))
bearing = math.degrees(math.atan2(x, y))
return (bearing + 360) % 360
@dataclass
class ARWorldCoordinate:
"""Local AR coordinate (meters from origin)"""
x: float # East
y: float # Up
z: float # North
def geo_to_local(geo: GeoCoordinate, origin: GeoCoordinate) -> ARWorldCoordinate:
"""Convert geographic to local AR coordinates"""
# Simplified planar projection (accurate for small areas)
lat_scale = 111320 # meters per degree latitude
lon_scale = 111320 * math.cos(math.radians(origin.latitude))
x = (geo.longitude - origin.longitude) * lon_scale # East
z = (geo.latitude - origin.latitude) * lat_scale # North
y = geo.altitude - origin.altitude # Up
return ARWorldCoordinate(x, y, z)
```
### Geofencing
```python
from enum import Enum
from typing import List, Callable
class GeofenceShape(Enum):
CIRCLE = "circle"
POLYGON = "polygon"
class Geofence:
"""Define trigger zones for AR content"""
def __init__(self, id: str, center: GeoCoordinate, radius: float):
self.id = id
self.center = center
self.radius = radius # meters
self.shape = GeofenceShape.CIRCLE
self.on_enter: List[Callable] = []
self.on_exit: List[Callable] = []
self.on_dwell: List[Callable] = []
self.dwell_time = 30 # seconds
def contains(self, point: GeoCoordinate) -> bool:
"""Check if point is inside geofence"""
return self.center.distance_to(point) <= self.radius
def add_enter_handler(self, callback: Callable):
self.on_enter.append(callback)
class GeofenceManager:
"""Manage multiple geofences"""
def __init__(self):
self.fences: dict[str, Geofence] = {}
self.active_fences: set[str] = set()
self.entry_times: dict[str, float] = {}
def add_fence(self, fence: Geofence):
self.fences[fence.id] = fence
def update_position(self, position: GeoCoordinate, timestamp: float):
"""Check geofences and trigger callbacks"""
currently_inside = set()
for fence_id, fence in self.fences.items():
if fence.contains(position):
currently_inside.add(fence_id)
# Trigger enter event
if fence_id not in self.active_fences:
self.entry_times[fence_id] = timestamp
for callback in fence.on_enter:
callback(fence, position)
# Check dwell time
elif timestamp - self.entry_times[fence_id] >= fence.dwell_time:
for callback in fence.on_dwell:
callback(fence, position)
# Trigger exit events
for fence_id in self.active_fences - currently_inside:
fence = self.fences[fence_id]
for callback in fence.on_exit:
callback(fence, position)
del self.entry_times[fence_id]
self.active_fences = currently_inside
```
## Visual Positioning
### ARCore Geospatial API Pattern
```kotlin
// Android/Kotlin with ARCore Geospatial API
class GeospatialManager(private val session: Session) {
fun placeAnchorAtLocation(
latitude: Double,
longitude: Double,
altitude: Double,
heading: Float
): Anchor? {
val earth = session.earth ?: return null
// Check tracking quality
if (earth.trackingState != TrackingState.TRACKING) {
return null
}
// Check horizontal accuracy
val pose = earth.cameraGeospatialPose
if (pose.horizontalAccuracy > 10) { // meters
return null // Not accurate enough
}
// Create geospatial anchor
val quaternion = Quaternion.axisAngle(
Vector3(0f, 1f, 0f),
Math.toRadians(heading.toDouble()).toFloat()
)
return earth.createAnchor(
latitude, longitude, altitude,
quaternion.x, quaternion.y, quaternion.z, quaternion.w
)
}
fun resolveTerrainAnchor(
latitude: Double,
longitude: Double,
heading: Float,
callback: (Anchor?) -> Unit
) {
val earth = session.earth ?: return callback(null)
// Terrain anchor automatically determines altitude
val future = earth.resolveAnchorOnTerrainAsync(
latitude, longitude,
0.0, // altitude above terrain
/* quaternion */ 0f, 0f, 0f, 1f,
{ anchor, state ->
when (state) {
Anchor.TerrainAnchorState.SUCCESS -> callback(anchor)
else -> callback(nullRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.