Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ARCHITECTURE_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Architecture Notes

## Overview

### Main App: iOSAccessAssessment

### Shared Code: PointNMapShared

Framework.
1,265 changes: 576 additions & 689 deletions IOSAccessAssessment.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@
ReferencedContainer = "container:IOSAccessAssessment.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A312FD842FA3391C0044808E"
BuildableName = "PointNMapSharedTests.xctest"
BlueprintName = "PointNMapSharedTests"
ReferencedContainer = "container:IOSAccessAssessment.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A312FD842FA3391C0044808E"
BuildableName = "PointNMapSharedTests.xctest"
BlueprintName = "PointNMapSharedTests"
ReferencedContainer = "container:IOSAccessAssessment.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand Down
5 changes: 3 additions & 2 deletions IOSAccessAssessment/ARCamera/TestCameraManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ARKit
import RealityKit
import Combine
import simd
import PointNMapShared

final class TestCameraManager: NSObject, ObservableObject, TestCameraProcessingDelegate {
var selectedClasses: [AccessibilityFeatureClass] = []
Expand Down Expand Up @@ -77,7 +78,7 @@ final class TestCameraManager: NSObject, ObservableObject, TestCameraProcessingD
self.metalContext = metalContext
self.isEnhancedAnalysisEnabled = isEnhancedAnalysisEnabled
self.meshGPUSnapshotGenerator = MeshGPUSnapshotGenerator(device: metalContext.device)
// try setUpPreAllocatedPixelBufferPools(size: Constants.SelectedAccessibilityFeatureConfig.inputSize)
// try setUpPreAllocatedPixelBufferPools(size: SharedAppConstants.SelectedAccessibilityFeatureConfig.inputSize)
self.cameraOutputImageCallback = cameraOutputImageCallback
self.isConfigured = true

Expand Down Expand Up @@ -206,7 +207,7 @@ extension TestCameraManager {
guard let segmentationPipeline = segmentationPipeline else {
throw ARCameraManagerError.segmentationNotConfigured
}
let croppedSize = Constants.SelectedAccessibilityFeatureConfig.inputSize
let croppedSize = SharedAppConstants.SelectedAccessibilityFeatureConfig.inputSize
let imageOrientation: CGImagePropertyOrientation = CameraOrientation.getCGImageOrientationForInterface(
currentInterfaceOrientation: interfaceOrientation
)
Expand Down
3 changes: 2 additions & 1 deletion IOSAccessAssessment/ARCamera/TestCameraViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ARKit
import CoreImage
import CoreImage.CIFilterBuiltins
import simd
import PointNMapShared

@MainActor
protocol TestCameraProcessingOutputConsumer: AnyObject {
Expand Down Expand Up @@ -331,7 +332,7 @@ final class TestCameraViewController: UIViewController, TestCameraProcessingOutp
) {
var totalVertexCount = 0
for accessibilityFeatureClass in accessibilityFeatureClasses {
guard Constants.SelectedAccessibilityFeatureConfig.classes.contains(accessibilityFeatureClass) else {
guard SharedAppConstants.SelectedAccessibilityFeatureConfig.classes.contains(accessibilityFeatureClass) else {
print("Invalid segmentation class: \(accessibilityFeatureClass)")
continue
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// IsExistingExtension.swift
// IOSAccessAssessment
//
// Created by Himanshu on 4/30/26.
//
import PointNMapShared
import CoreLocation
import MapKit

extension AttributeEstimationPipeline {
func processIsExistingRequest(
deviceLocation: CLLocationCoordinate2D,
mappingData: CurrentMappingData,
accessibilityFeature: MappedEditableAccessibilityFeature
) {
/// Threshold needs to be in Map Units
let distanceThreshold = PointNMapConstants.WorkspaceConstants.fetchUpdateRadiusThresholdInMeters * MKMapPointsPerMeterAtLatitude(deviceLocation.latitude)
guard let LocationDetails = accessibilityFeature.locationDetails else {
accessibilityFeature.setIsExisting(false)
return
}
let matchedElement: (any OSWElement)? = mappingData.getMatchedFeature(
to: LocationDetails, featureClass: accessibilityFeature.accessibilityFeatureClass,
captureId: self.captureImageData?.id,
distanceThreshold: distanceThreshold
)
guard let matchedElement = matchedElement else {
accessibilityFeature.setIsExisting(false)
return
}
let isExisting = accessibilityFeature.accessibilityFeatureClass.kind.oswPolicy.isExistingFirst
accessibilityFeature.setIsExisting(isExisting)
accessibilityFeature.setOSWElement(oswElement: matchedElement)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// AccessibilityFeatureAttribute.swift
// IOSAccessAssessment
//
// Created by Himanshu on 11/9/25.
//

import Foundation
import PointNMapShared

/**
Enumeration defining various accessibility feature attributes, along with their metadata and value types.

- Note: One needs to be aware of the value types associated with each attribute. The valueType property is only meant for reference.
*/
extension AccessibilityFeatureAttribute {
/// TODO: Verify these OSM tag keys
public var osmTagKey: String {
switch self {
case .width: return "width"
case .runningSlope: return "incline"
case .crossSlope: return "cross_slope"
case .surfaceIntegrity: return "surface_integrity"
case .lidarDepth: return APIConstants.TagKeys.lidarDepthKey
case .latitudeDelta: return APIConstants.TagKeys.latitudeDeltaKey
case .longitudeDelta: return APIConstants.TagKeys.longitudeDeltaKey
case .widthLegacy: return "width_legacy"
case .runningSlopeLegacy: return "incline_legacy"
case .crossSlopeLegacy: return "cross_slope_legacy"
case .widthFromImage: return "width_from_image"
case .runningSlopeFromImage: return "running_slope_from_image"
case .crossSlopeFromImage: return "cross_slope_from_image"
default: return ""
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// AccessibilityFeatureKindExtension.swift
// IOSAccessAssessment
//
// Created by Himanshu on 4/30/26.
//

import PointNMapShared

/**
Extension to add mapping-related logic to AccessibilityFeatureKind.
*/
extension AccessibilityFeatureKind {
var oswPolicy: OSWPolicy {
switch self {
case .sidewalk: return OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true)
case .building: return OSWPolicy(oswElementClass: .Building, isExistingFirst: false)
case .pole: return OSWPolicy(oswElementClass: .Pole, isExistingFirst: false)
case .trafficLight: return OSWPolicy(oswElementClass: .TrafficLight, isExistingFirst: false)
case .trafficSign: return OSWPolicy(oswElementClass: .TrafficSign, isExistingFirst: false)
case .vegetation: return OSWPolicy(oswElementClass: .Vegetation, isExistingFirst: false)
default: return OSWPolicy.default
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
import Foundation
import CoreImage

import PointNMapShared

extension AccessibilityFeatureConfig {
static let cityscapes: AccessibilityFeatureClassConfig = AccessibilityFeatureClassConfig(
Expand All @@ -33,14 +33,12 @@ extension AccessibilityFeatureConfig {
AccessibilityFeatureClass(
id: "road", name: "Road", grayscaleValue: 7.0 / 255.0, labelValue: 7,
color: CIColor(red: 0.502, green: 0.251, blue: 0.502),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4)
),
AccessibilityFeatureClass(
id: "sidewalk", name: "Sidewalk", grayscaleValue: 8.0 / 255.0, labelValue: 8,
color: CIColor(red: 0.957, green: 0.137, blue: 0.910),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4)
),
AccessibilityFeatureClass(
id: "parking", name: "Parking", grayscaleValue: 9.0 / 255.0, labelValue: 9,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
import Foundation
import CoreImage

import PointNMapShared

extension AccessibilityFeatureConfig {
static let cityscapesSubset: AccessibilityFeatureClassConfig = AccessibilityFeatureClassConfig(
Expand All @@ -16,13 +16,11 @@ extension AccessibilityFeatureConfig {
id: "road", name: "Road", grayscaleValue: 0.0 / 255.0, labelValue: 0,
color: CIColor(red: 0.502, green: 0.251, blue: 0.502),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
),
AccessibilityFeatureClass(
id: "sidewalk", name: "Sidewalk", grayscaleValue: 1.0 / 255.0, labelValue: 1,
color: CIColor(red: 0.957, green: 0.137, blue: 0.910),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
),
AccessibilityFeatureClass(
id: "building", name: "Building", grayscaleValue: 2.0 / 255.0, labelValue: 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
import Foundation
import CoreImage
import PointNMapShared

extension AccessibilityFeatureConfig {
static let cocoCustom35Config: AccessibilityFeatureClassConfig = AccessibilityFeatureClassConfig(
Expand All @@ -14,14 +15,12 @@ extension AccessibilityFeatureConfig {
AccessibilityFeatureClass(
id: "road", name: "Road", grayscaleValue: 27.0 / 255.0, labelValue: 27,
color: CIColor(red: 0.502, green: 0.251, blue: 0.502),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4)
),
AccessibilityFeatureClass(
id: "sidewalk", name: "Sidewalk", grayscaleValue: 22.0 / 255.0, labelValue: 22,
color: CIColor(red: 0.957, green: 0.137, blue: 0.910),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4)
),
AccessibilityFeatureClass(
id: "building", name: "Building", grayscaleValue: 16.0 / 255.0, labelValue: 16,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
//
import Foundation
import CoreImage


import PointNMapShared

extension AccessibilityFeatureConfig {
static let cocoCustom53Config: AccessibilityFeatureClassConfig = AccessibilityFeatureClassConfig(
Expand All @@ -16,14 +15,12 @@ extension AccessibilityFeatureConfig {
AccessibilityFeatureClass(
id: "road", name: "Road", grayscaleValue: 41.0 / 255.0, labelValue: 41,
color: CIColor(red: 0.502, green: 0.251, blue: 0.502),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4)
),
AccessibilityFeatureClass(
id: "sidewalk", name: "Sidewalk", grayscaleValue: 35.0 / 255.0, labelValue: 35,
color: CIColor(red: 0.957, green: 0.137, blue: 0.910),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4)
),
AccessibilityFeatureClass(
id: "building", name: "Building", grayscaleValue: 19.0 / 255.0, labelValue: 19,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
import Foundation
import CoreImage
import PointNMapShared


extension AccessibilityFeatureConfig {
Expand Down Expand Up @@ -60,7 +61,6 @@ extension AccessibilityFeatureConfig {
id: "person", name: "Person", grayscaleValue: 180.0 / 255.0, labelValue: 180,
color: CIColor(red: 0.750, green: 0.500, blue: 0.500),
bounds: CGRect(x: 0.0, y: 0.1, width: 1.0, height: 0.4),
oswPolicy: OSWPolicy(oswElementClass: .Sidewalk, isExistingFirst: true), // Temporarily set for testing
),
AccessibilityFeatureClass(
id: "pottedplant", name: "PottedPlant", grayscaleValue: 192.0 / 255.0, labelValue: 192,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
//
import Foundation
import CoreLocation
import PointNMapShared

struct MappedAccessibilityFeature: AccessibilityFeatureProtocol, Sendable, CustomStringConvertible {
let id: UUID

let accessibilityFeatureClass: AccessibilityFeatureClass

var locationDetails: OSMLocationDetails?
var locationDetails: LocationDetails?
var oswElement: any OSWElement

var attributeValues: [AccessibilityFeatureAttribute: AccessibilityFeatureAttribute.Value?] = [:]
Expand All @@ -34,7 +35,7 @@ struct MappedAccessibilityFeature: AccessibilityFeatureProtocol, Sendable, Custo
init(
id: UUID = UUID(),
accessibilityFeatureClass: AccessibilityFeatureClass,
locationDetails: OSMLocationDetails?,
locationDetails: LocationDetails?,
attributeValues: [AccessibilityFeatureAttribute: AccessibilityFeatureAttribute.Value?] = [:],
experimentalAttributeValues: [AccessibilityFeatureAttribute : AccessibilityFeatureAttribute.Value?] = [:],
oswElement: any OSWElement
Expand All @@ -53,7 +54,7 @@ struct MappedAccessibilityFeature: AccessibilityFeatureProtocol, Sendable, Custo
return lastCoordinate
}

mutating func setLocationDetails(locationDetails: OSMLocationDetails) {
mutating func setLocationDetails(locationDetails: LocationDetails) {
self.locationDetails = locationDetails
}

Expand Down Expand Up @@ -84,6 +85,6 @@ struct MappedAccessibilityFeature: AccessibilityFeatureProtocol, Sendable, Custo
}

var description: String {
return "MappedAccessibilityFeature(id: \(id), class: \(accessibilityFeatureClass), location: \(String(describing: locationDetails)), attributes: \(attributeValues), oswElement: \(oswElement))"
return "MappedAccessibilityFeature(id: \(id), class: \(accessibilityFeatureClass), location: \(String(describing: locationDetails)), attributes: \(attributeValues))"
}
}
Loading