Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating more filter options #101

Merged
merged 19 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from 11 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
4 changes: 4 additions & 0 deletions apps/ios/GuideDogs.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@
91C82AAD2A5DCF040086D126 /* GeolocationManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91C82AAC2A5DCF040086D126 /* GeolocationManagerTest.swift */; };
91C82ABE2A6B08500086D126 /* RouteGuidanceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91C82ABD2A6B08500086D126 /* RouteGuidanceTest.swift */; };
91DC0CF92A46134600244CC8 /* GeometryUtilsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 914DEBDC2A3CE901007B161C /* GeometryUtilsTest.swift */; };
AC3A3EE22C40C9080061EEB8 /* NearbyTableFilterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC3A3EE12C40C9080061EEB8 /* NearbyTableFilterTest.swift */; };
B90C27D61EAF81D600007368 /* Sound.swift in Sources */ = {isa = PBXBuildFile; fileRef = B90C27D51EAF81D600007368 /* Sound.swift */; };
B918EE9825100FFF00A5354A /* CalloutRangeContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = B918EE9725100FFF00A5354A /* CalloutRangeContext.swift */; };
B91D3F6427AB5546004159A8 /* UserAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B91D3F6327AB5546004159A8 /* UserAction.swift */; };
Expand Down Expand Up @@ -1587,6 +1588,7 @@
915FF9F42ADE3F91002B3690 /* AuthoredActivityContentTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthoredActivityContentTest.swift; sourceTree = "<group>"; };
91C82AAC2A5DCF040086D126 /* GeolocationManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = " GeolocationManagerTest.swift"; path = "UnitTests/Sensors/Geolocation/Geolocation Manager/ GeolocationManagerTest.swift"; sourceTree = SOURCE_ROOT; };
91C82ABD2A6B08500086D126 /* RouteGuidanceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RouteGuidanceTest.swift; path = "UnitTests/Behaviors/Route Guidance/RouteGuidanceTest.swift"; sourceTree = SOURCE_ROOT; };
AC3A3EE12C40C9080061EEB8 /* NearbyTableFilterTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyTableFilterTest.swift; sourceTree = "<group>"; };
B90C27D51EAF81D600007368 /* Sound.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Sound.swift; path = Code/Audio/Protocols/Sound.swift; sourceTree = "<group>"; };
B918EE9725100FFF00A5354A /* CalloutRangeContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalloutRangeContext.swift; sourceTree = "<group>"; };
B91D3F6327AB5546004159A8 /* UserAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserAction.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4283,6 +4285,7 @@
isa = PBXGroup;
children = (
914BAAF22AD745E400CB2171 /* DestinationManagerTest.swift */,
AC3A3EE12C40C9080061EEB8 /* NearbyTableFilterTest.swift */,
);
path = "Destination Manager";
sourceTree = "<group>";
Expand Down Expand Up @@ -5545,6 +5548,7 @@
914BAAFD2AD7483300CB2171 /* AudioEngineTest.swift in Sources */,
914BAAF32AD745E400CB2171 /* DestinationManagerTest.swift in Sources */,
91C82ABE2A6B08500086D126 /* RouteGuidanceTest.swift in Sources */,
AC3A3EE22C40C9080061EEB8 /* NearbyTableFilterTest.swift in Sources */,
91C82AAD2A5DCF040086D126 /* GeolocationManagerTest.swift in Sources */,
91DC0CF92A46134600244CC8 /* GeometryUtilsTest.swift in Sources */,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,12 @@
/* Filters, Transit */
"filter.transit" = "Public Transit";

/* Filters, Landmarks */
"filter.landmarks" = "Landmarks";

/* Filters, Parks */
"filter.park" = "Park";

/* Displayed next to the name of the filter to indicate that the filter is currently selected. %@ is the name of a filter */
"filter.selected" = "%@ (selected)";

Expand Down Expand Up @@ -3214,12 +3220,6 @@
/* Open Street Map term. Refers to any parking space designed for bicycles, where one can leave a pedal cycle unattended in reasonable security. */
"osm.tag.bike_parking" = "Bike Parking";

/* Open Street Map term. An informal place with sit-down facilities selling beverages and light meals and/or snacks. */
"osm.tag.cafe" = "Cafe";

/* Open Street Map term. Generally a formal eating places with sit-down facilities selling full meals served by waiters and often licensed (where allowed) to sell alcoholic drinks. */
"osm.tag.restaurant" = "Restaurant";

/* Open Street Map term. A public telephone, phone box, or telephone on a stand or wall. Usually you pay to use them, often only via a pre-pay card. */
"osm.tag.telephone" = "Telephone";

Expand All @@ -3240,10 +3240,30 @@

/* Open Street Map term. A bus stop is a place where passengers can board or alight from a bus. Its position may be marked by a shelter, pole, bus lay-by, or road markings. */
"osm.tag.bus_stop" = "Bus Stop";
/* Open Street Map term. A bus stop is a place where passengers can go to a landmark */
"osm.tag.landmark" = "Landmark";

/* Open Street Map term. Used as a display name for place or a location. %@ is a bus stop name, such as "London Bus Stop". */
"osm.tag.bus_stop.named" = "%@ Bus Stop";

/* Open Street Map term. An informal place with sit-down facilities selling beverages and light meals and/or snacks. */
"osm.tag.cafe" = "Cafe";

/* Open Street Map term. Generally a formal eating places with sit-down facilities selling full meals served by waiters and often licensed (where allowed) to sell alcoholic drinks. */
"osm.tag.restaurant" = "Restaurant";

/* Open Street Map term. Fast food is a place where food that is prepared and served very quickly. */
"osm.tag.fast_food" = "fast_food";

/* Open Street Map term. A bar is an place where alcoholic beverages are served. */
"osm.tag.bar" = "bar";

/* Open Street Map term. An ice cream shop is a place where ice cream is sold. */
"osm.tag.ice_cream" = "amenity=ice_cream";

/* Open Street Map term. A pub is a place selling beer and other alcoholic drinks; may also provide food or accommodation (UK). */
"osm.tag.pub" = "amenity=pub";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't include amenity= here. These should be the tag values, not keys.


/* Open Street Map term. Used as a display name for place or a location. %@ is a bus stop id, such as "Bus Stop 7" or "Bus Stop B". */
"osm.tag.bus_stop.refed" = "Bus Stop %@";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,131 @@ extension GDASpatialDataResultEntity: Typeable {

func isOfType(_ type: PrimaryType) -> Bool {
switch type {
case .transit: return isOfType(.transitStop)
case .transit:
return isOfType(.transitStop)
case .food:
return isFood()
case .landmarks:
return isLandmarks()
case .park:
return isPark()
case .hotel:
return isHotel()
}
}

func isOfType(_ type: SecondaryType) -> Bool {
switch type {
case .transitStop: return isTransitStop()
case .transitStop:
return isTransitStop()
case .food:
return isFood()
case .landmarks:
return isLandmarks()
case .park:
return isPark()
case .hotel:
return isHotel()
}
}

private func isTransitStop() -> Bool {
print("Raw superCategory: \(superCategory)")
guard let category = SuperCategory(rawValue: superCategory) else {
print("Failed to map superCategory to SuperCategory enum")
return false
}
print("Mapped category: \(category)")
let isTransitLocation = category == .mobility && localizedName.lowercased().contains(GDLocalizedString("osm.tag.bus_stop").lowercased())
print("Transit location check: \(isTransitLocation)")
if isTransitLocation {
print("Transit location found: \(localizedName)")
}
return isTransitLocation
}

//convinence store
private func isFood() -> Bool {
print("Raw superCategory: \(superCategory)")
guard let category = SuperCategory(rawValue: superCategory) else {
print("Failed to map superCategory to SuperCategory enum")
return false
}
print("Mapped category: \(category)")
let isFoodLocation = category == .places &&
localizedName.lowercased().contains(GDLocalizedString("osm.tag.restaurant").lowercased())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was suggesting matching the amenity attribute of the place, rather than its name. I haven't tested this, but I'm thinking all you'd have to do is something like:

let isFoodLocation = amenity == GDLocalizedString("osm.tag.restaurant")

where amenity should be recognized as a field of GDASpatialDataResultEntity per

// let osmTags = ["amenity=restaurant", "amenity=bar", "amenity=cafe", "amenity=fast_food", "amenity=ice_cream", "amenity=pub"]

// List of restaurant-related OSM tags using localized strings
print("Transit location check: \(isFoodLocation)")

return category == .mobility && localizedName.lowercased().contains(GDLocalizedString("osm.tag.bus_stop").lowercased())
if isFoodLocation {
print("Food location found: \(localizedName)")
}

return isFoodLocation
}




private func isLandmarks() -> Bool {
guard let category = SuperCategory(rawValue: superCategory) else {
return false
}

let landmarkKeywords = ["monument", "statue", "museum", "historic", "landmark", "cathedral"]

for keyword in landmarkKeywords {
if localizedName.lowercased().contains(keyword) {
return true
}
}

return category == .landmarks
}

private func isPark() -> Bool {
guard let category = SuperCategory(rawValue: superCategory) else {
return false
}

let parkKeywords = [
"park", "garden", "green space", "recreation area", "playground",
"nature reserve", "botanical garden", "public garden", "field", "reserve"
]

// Keywords to exclude parking lots
let excludeKeywords = [
"parking lot", "car park", "parking", "garage", "park and ride"
]

let lowercasedName = localizedName.lowercased()

// Check if the name contains any park keyword
var containsParkKeyword = false
for keyword in parkKeywords {
if lowercasedName.contains(keyword) {
containsParkKeyword = true
break
}
}

// Check if the name contains any exclude keyword
var containsExcludeKeyword = false
for keyword in excludeKeywords {
if lowercasedName.contains(keyword) {
containsExcludeKeyword = true
break
}
}

return containsParkKeyword && !containsExcludeKeyword
}



private func isHotel() -> Bool {
return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ enum SuperCategory: String {
case landmarks = "landmark"
case places = "place"
case mobility = "mobility"
case foods = "food"
case parks = "park"
case information = "information"
case objects = "object"
case safety = "safety"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import Foundation
enum PrimaryType: String, CaseIterable, Type {

case transit
case food
case landmarks
case park
case hotel

func matches(poi: POI) -> Bool {
guard let typeable = poi as? Typeable else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import Foundation
enum SecondaryType: Type {

case transitStop
case food
case landmarks
case park
case hotel

func matches(poi: POI) -> Bool {
guard let typeable = poi as? Typeable else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,30 @@ class GeoJsonFeature {
return
}

//TODO JON
if value == "fast_food"{
superCategory = SuperCategory.foods
return
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this not work to assign the supercategory? This feels like the right place to be doing the classification of GeoJSON features, so the later filtering logic can be based entirely on the superCategory field.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think you can do the category assignment here. When the OSM feature is tagged with e.g. leisure=playground, the local variable type will be leisure here, and value will be playground.


if value == "restaurants"{
superCategory = SuperCategory.foods
return
}


if value == "food"{
superCategory = SuperCategory.foods
return
}


if value == "deli"{
superCategory = SuperCategory.foods
return
}


// Case: Banks
if value == "bank" {
superCategory = SuperCategory.places
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ struct NearbyTableFilter: Equatable {
static var defaultFilters: [NearbyTableFilter] {
return [
.defaultFilter,
NearbyTableFilter(type: .transit)
NearbyTableFilter(type: .transit),
NearbyTableFilter(type: .food),
NearbyTableFilter(type: .landmarks),
NearbyTableFilter(type: .park),
NearbyTableFilter(type: .hotel)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent with pluralization, both in variable names and displayed strings. Transit and Food are both collective nouns, but Landmarks, Parks, and Hotels need a trailing "s".

]
}

Expand Down Expand Up @@ -50,12 +54,24 @@ struct NearbyTableFilter: Equatable {
self.type = type

if let type = type {
switch type {
case .transit:
self.localizedString = GDLocalizedString("filter.transit")
self.image = UIImage(named: "Transit")
}
} else {
switch type {
case .transit:
self.localizedString = GDLocalizedString("filter.transit")
self.image = UIImage(named: "Transit")
case .food:
self.localizedString = GDLocalizedString("filter.food_drink")
self.image = UIImage(named: "Food and Drinks")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these icons exist? I see an image next to Transit, but not the others.

case .landmarks:
self.localizedString = GDLocalizedString("filter.landmarks")
self.image = UIImage(named: "Landmarks")
case .park:
self.localizedString = GDLocalizedString("filter.park")
self.image = UIImage(named: "Parks")
case .hotel:
self.localizedString = GDLocalizedString("filter.hotel")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This key is missing from the English localizations.

self.image = UIImage(named: "Hotel")
}
} else {
// There is no `PrimaryType` filter selected
self.localizedString = GDLocalizedString("filter.all")
self.image = UIImage(named: "AllPlaces")
Expand Down
Loading