bae705aa97
- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
325 lines
8.5 KiB
Markdown
325 lines
8.5 KiB
Markdown
# QUIXZOOM Urban Knowledge Graph (UKG)
|
|
|
|
## Den verkliga "hjärnan" i QUIXZOOM
|
|
|
|
> "AI-modeller kan bytas ut och förbättras över tid, men en väldesignad kunskapsgraf med observationer, evidens och historik blir en långsiktig strategisk tillgång som är svår att återskapa."
|
|
|
|
---
|
|
|
|
## Tre Lager
|
|
|
|
### 1. Observation Layer
|
|
|
|
```
|
|
Video
|
|
↓
|
|
Frame Extraction
|
|
↓
|
|
Observation Engine ← AI detekterar objekt
|
|
↓
|
|
Knowledge Graph ← Sparas som strukturerade observationer
|
|
```
|
|
|
|
**Istället för att spara "bilder" sparar vi observationer:**
|
|
|
|
```json
|
|
{
|
|
"id": "obs_1782638086138_ab6ndwzwo",
|
|
"timestamp": "2026-06-28T08:15:30Z",
|
|
"source": {
|
|
"type": "quixzoom",
|
|
"id": "zoomer_001"
|
|
},
|
|
"media": {
|
|
"type": "video",
|
|
"url": "https://r2.landvex.com/videos/bangkok_001.mp4",
|
|
"frameNumber": 342
|
|
},
|
|
"observedObjects": [{
|
|
"objectId": "street_lamp_3e6a09cfabc7",
|
|
"confidence": 0.94,
|
|
"bbox": [100, 200, 150, 300]
|
|
}],
|
|
"location": { "lat": 13.725, "lng": 100.555 },
|
|
"quality": { "resolution": 1080, "sharpness": 0.9 }
|
|
}
|
|
```
|
|
|
|
### 2. Evidence Layer
|
|
|
|
**Samma gatlykta i hundra videor = ett objekt med hundra bevis:**
|
|
|
|
```
|
|
Street Lamp #1293
|
|
├── Evidence
|
|
│ ├── Video A, Frame 342 (Zoomer 001)
|
|
│ ├── Video B, Frame 91 (Zoomer 002)
|
|
│ ├── QUIXZOOM Capture (Zoomer 003)
|
|
│ ├── Inspector Capture (Municipality)
|
|
│ └── Municipality Capture (Official)
|
|
└── Confidence: 0.98 (från multipla källor)
|
|
```
|
|
|
|
**Skalbart och verifierbart över tid.**
|
|
|
|
### 3. Temporal Layer
|
|
|
|
**Förändring över tid — det är här Landvex-värdet ligger:**
|
|
|
|
```
|
|
Street Lamp #1293
|
|
|
|
2026-06-01 OK
|
|
2026-08-12 Lutning upptäckt (0° → 2°)
|
|
2026-09-20 Korrosion ökar, ljus flimrar
|
|
2026-10-11 Belysning trasig
|
|
2026-11-02 UTBYTT
|
|
```
|
|
|
|
**Användning:**
|
|
- Modellera förändringstakt
|
|
- Förutsäga underhållsbehov
|
|
- Upptäcka avvikelser
|
|
- Planera inspektioner
|
|
|
|
---
|
|
|
|
## Arkitektur
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ URBAN KNOWLEDGE GRAPH │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ Observation │ │ Evidence │ │ Temporal │ │
|
|
│ │ Layer │ │ Layer │ │ Layer │ │
|
|
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
│ │ │ │ │
|
|
│ └────────────────┼────────────────┘ │
|
|
│ │ │
|
|
│ ┌─────┴─────┐ │
|
|
│ │ Object │ │
|
|
│ │ Entity │ │
|
|
│ └─────┬─────┘ │
|
|
│ │ │
|
|
│ ┌────────────────┼────────────────┐ │
|
|
│ ▼ ▼ ▼ │
|
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
│ │ Spatial │ │ Type │ │ Relation│ │
|
|
│ │ Index │ │ Index │ │ Graph │ │
|
|
│ └─────────┘ └─────────┘ └─────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Objekt-struktur
|
|
|
|
```json
|
|
{
|
|
"id": "street_lamp_3e6a09cfabc7",
|
|
"type": "street_lamp",
|
|
"subtype": "led",
|
|
|
|
"location": {
|
|
"lat": 13.725,
|
|
"lng": 100.555,
|
|
"accuracy": 2,
|
|
"altitude": 15
|
|
},
|
|
|
|
"attributes": {
|
|
"material": "steel",
|
|
"height": 7.8,
|
|
"paint": "grey",
|
|
"rust": false,
|
|
"lean": 0,
|
|
"light": "working"
|
|
},
|
|
|
|
"status": "active",
|
|
"verificationStatus": "verified",
|
|
"confidence": 0.94,
|
|
"uncertainty": 0.06,
|
|
|
|
"observationIds": ["obs_xxx", "obs_yyy"],
|
|
"evidenceIds": ["ev_xxx", "ev_yyy", "ev_zzz"],
|
|
"temporalIds": ["tmp_xxx", "tmp_yyy"],
|
|
"relationIds": ["rel_xxx"]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Integration
|
|
|
|
### iOS-appen skriver observationer
|
|
|
|
```swift
|
|
// Zoomer dokumenterar gatlykta
|
|
let observation = Observation(
|
|
source: .quixzoom(zoomerId: "zoomer_001"),
|
|
media: .video(url: videoURL, frame: 342),
|
|
observedObjects: [
|
|
ObservedObject(
|
|
type: .streetLamp,
|
|
confidence: 0.94,
|
|
attributes: [
|
|
.material: "steel",
|
|
.height: 7.8,
|
|
.light: .working
|
|
]
|
|
)
|
|
],
|
|
location: gpsLocation
|
|
)
|
|
|
|
// Skicka till UKG
|
|
ukg.addObservation(observation)
|
|
```
|
|
|
|
### WebSocket-servern skickar uppdateringar
|
|
|
|
```javascript
|
|
// Server skickar instruktion baserat på UKG
|
|
const gaps = ukg.identifyKnowledgeGaps(areaId);
|
|
const topGap = gaps[0];
|
|
|
|
ws.send({
|
|
type: 'instruction',
|
|
text: `Dokumentera ${topGap.description}`,
|
|
reason: `Knowledge gap: ${topGap.type}`
|
|
});
|
|
```
|
|
|
|
### Active Learning frågar grafen
|
|
|
|
```javascript
|
|
// Vilka kunskapsgap finns?
|
|
const gaps = ukg.identifyKnowledgeGaps('bangkok');
|
|
|
|
// Vilka objekt behöver verifiering?
|
|
const needsVerification = ukg.findObjectsByVerificationStatus('unverified');
|
|
|
|
// Vilka områden saknar data?
|
|
const uncovered = ukg.findUncoveredAreas('bangkok');
|
|
```
|
|
|
|
### Mission Mode genereras från UKG
|
|
|
|
```javascript
|
|
// Skapa uppdrag baserat på grafens behov
|
|
const mission = {
|
|
type: 'verify',
|
|
targetObject: ukg.findObjectWithLowConfidence(),
|
|
reason: 'Object confidence below threshold'
|
|
};
|
|
```
|
|
|
|
### Adaptive Intelligence planerar från UKG
|
|
|
|
```javascript
|
|
// Vad vet vi redan?
|
|
const knowledge = ukg.getAreaKnowledge('bangkok');
|
|
|
|
// Vad saknas?
|
|
const gaps = ukg.identifyKnowledgeGaps('bangkok');
|
|
|
|
// Planera nästa observation
|
|
const nextObservation = planner.planNext(knowledge, gaps);
|
|
```
|
|
|
|
---
|
|
|
|
## API
|
|
|
|
### Skapa objekt
|
|
|
|
```javascript
|
|
const lamp = ukg.createObject({
|
|
type: 'street_lamp',
|
|
location: { lat: 13.725, lng: 100.555 },
|
|
attributes: { material: 'steel', height: 7.8 }
|
|
});
|
|
```
|
|
|
|
### Lägg till observation
|
|
|
|
```javascript
|
|
ukg.addObservation({
|
|
sourceType: 'quixzoom',
|
|
sourceId: 'zoomer_001',
|
|
mediaType: 'video',
|
|
mediaUrl: 'https://r2.landvex.com/videos/xxx.mp4',
|
|
frameNumber: 342,
|
|
observedObjects: [{ objectId: lamp.id, confidence: 0.94 }],
|
|
location: { lat: 13.725, lng: 100.555 }
|
|
});
|
|
```
|
|
|
|
### Lägg till evidens
|
|
|
|
```javascript
|
|
ukg.addEvidence({
|
|
objectId: lamp.id,
|
|
proofType: 'video',
|
|
proofUrl: 'https://r2.landvex.com/videos/xxx.mp4#frame=342',
|
|
sourceType: 'quixzoom',
|
|
reliability: 0.85
|
|
});
|
|
```
|
|
|
|
### Hämta temporal historik
|
|
|
|
```javascript
|
|
const history = ukg.getTemporalHistory(lamp.id);
|
|
// Returns: [{ timestamp, state: { attributes }, changes, reason }]
|
|
```
|
|
|
|
### Sök närliggande objekt
|
|
|
|
```javascript
|
|
const nearby = ukg.findNearbyObjects(
|
|
{ lat: 13.725, lng: 100.555 },
|
|
50 // radius in meters
|
|
);
|
|
```
|
|
|
|
### Hitta objekt efter typ
|
|
|
|
```javascript
|
|
const lamps = ukg.findObjectsByType('street_lamp', bangkokArea);
|
|
```
|
|
|
|
### Merge objekt (hundra videor → ett objekt)
|
|
|
|
```javascript
|
|
ukg.mergeObjects(mainLampId, [duplicateLampId1, duplicateLampId2]);
|
|
```
|
|
|
|
---
|
|
|
|
## Filstruktur
|
|
|
|
```
|
|
urban-knowledge-graph/
|
|
├── ukg.js # Huvudklass
|
|
└── README-UKG.md # Denna fil
|
|
```
|
|
|
|
---
|
|
|
|
## Nästa steg
|
|
|
|
1. **Persistens**: Spara till PostgreSQL/Neo4j
|
|
2. **Realtid**: WebSocket-uppdateringar
|
|
3. **Query API**: GraphQL för komplexa frågor
|
|
4. **Visualisering**: Karta med objekt
|
|
5. **Export**: SIE4, GeoJSON, CityGML
|
|
|
|
---
|
|
|
|
*LandveX Inc. — Urban Knowledge Graph: Den verkliga hjärnan i QUIXZOOM.*
|