-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #41 from SEbbaDK/generic-quests
Generic quests + second quest
- Loading branch information
Showing
14 changed files
with
496 additions
and
336 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:latlong/latlong.dart'; | ||
import 'package:osm_api/osm_api.dart' as osm; | ||
|
||
import 'package:client/quests/simple_tag_quest.dart'; | ||
import 'package:client/quests/quest_finder.dart'; | ||
import 'package:client/quests/quest.dart'; | ||
|
||
class BackrestBenchQuestFinder implements QuestFinder { | ||
@override | ||
Quest construct(osm.Element e) => BackrestBenchQuest(e); | ||
|
||
@override | ||
bool applicable(osm.Element e) => | ||
e.isNode && | ||
e.tags['amenity'] == 'bench' && | ||
!e.tags.containsKey('backrest'); | ||
} | ||
|
||
class BackrestBenchQuest extends SimpleTagQuest { | ||
BackrestBenchQuest(osm.Element element) : super(element); | ||
|
||
@override | ||
String tag() => 'backrest'; | ||
|
||
@override | ||
question() => 'Does the bench have a backrest?'; | ||
|
||
@override | ||
String changesetComment() => 'Added backrest tag for a bench'; | ||
|
||
@override | ||
Widget icon() => Icon(Icons.airline_seat_recline_normal_sharp); | ||
|
||
@override | ||
Map<String, String> possibilitiesToTags() => {'Yes': 'yes', 'No': 'no'}; | ||
} |
123 changes: 123 additions & 0 deletions
123
client/lib/quests/building_quests/building_type_quest.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:latlong/latlong.dart'; | ||
import 'package:osm_api/osm_api.dart' as osm; | ||
|
||
import 'package:client/quests/simple_tag_quest.dart'; | ||
import 'package:client/quests/quest.dart'; | ||
import 'package:client/quests/quest_finder.dart'; | ||
|
||
class BuildingTypeQuestFinder implements QuestFinder { | ||
@override | ||
Quest construct(osm.Element e) => BuildingTypeQuest(e); | ||
|
||
@override | ||
bool applicable(osm.Element e) => | ||
e.isWay && | ||
e.tags['building'] == "yes"; | ||
} | ||
|
||
class BuildingTypeQuest extends SimpleTagQuest { | ||
BuildingTypeQuest(osm.Element element) : super(element); | ||
|
||
String tag() => 'building'; | ||
|
||
@override | ||
String question() => "What type of building is this?"; | ||
|
||
@override | ||
String changesetComment() => "Added buildingtype tag to a building"; | ||
|
||
@override | ||
Widget icon() => Icon(Icons.house); | ||
|
||
@override | ||
Map<String, String> possibilitiesToTags() => { | ||
//Accomodation | ||
'Apartments': 'apartments', | ||
'Bungalow': 'bungalow', | ||
'Cabin': 'cabin', | ||
'Detached': 'detached', | ||
'Dormitory': 'dormitory', | ||
'Farm': 'farm', | ||
'Ger': 'ger', | ||
'Hotel': 'hotel', | ||
'House': 'house', | ||
'Houseboat': 'houseboat', | ||
'Residential': 'residential', | ||
'Semidetached house': 'semidetached_house', | ||
'Static caravan': 'static_caravan', | ||
'Terrace': 'terrace', | ||
// Commercial | ||
'Commercial': 'commercial', | ||
'Industrial': 'industrial', | ||
'Kiosk': 'kiosk', | ||
'Office': 'office', | ||
'Retail': 'retail', | ||
'Supermarket': 'supermarket', | ||
'Warehouse': 'warehouse', | ||
// Religious | ||
'Cathedral': 'cathedral', | ||
'Chapel': 'chapel', | ||
'Church': 'church', | ||
'Monastery': 'monastery', | ||
'Mosque': 'mosque', | ||
'Presbytery': 'presbytery', | ||
'Religious': 'religious', | ||
'Shine': 'shine', | ||
'Synagogue': 'synagogue', | ||
'Temple': 'temple', | ||
//Civic/Amenity | ||
'Bakehouse': 'bakehouse', | ||
'Civic': 'civic', | ||
'Fire station': 'fire_station', | ||
'Government': 'government', | ||
'Hospital': 'hospital', | ||
'Public': 'public', | ||
'Toilets': 'toilets', | ||
'Train station': 'train_station', | ||
'Transportation': 'transportation', | ||
'Kindergarten': 'kindergarten', | ||
'School': 'school', | ||
'University': 'university', | ||
'College': 'college', | ||
//Agriculture | ||
'Barn': 'barn', | ||
'Conservatory': 'conservatory', | ||
'Cowshed': 'cowshed', | ||
'Farm auxiliary': 'farm_auxiliary', | ||
'Greenhouse': 'greenhouse', | ||
'Slurry tank': 'slurry_tank', | ||
'Stable': 'stable', | ||
'Sty': 'sty', | ||
//spots | ||
'Grandstand': 'grandstand', | ||
'Pavilion': 'pavilion', | ||
'Riding hall': 'riding_hall', | ||
'Sports hall': 'sports_hall', | ||
'Stadium': 'stadium', | ||
//Storage | ||
'Hangar': 'hangar', | ||
'Hut': 'hut', | ||
'Shed': 'shed', | ||
//Cars | ||
'Carport': 'carport', | ||
'Garage': 'garage', | ||
'Garages': 'garages', | ||
'Parking': 'parking', | ||
//Power | ||
'Digester': 'digester', | ||
'Service': 'service', | ||
'Transformer tower': 'transformer_tower', | ||
'Water tower': 'water_tower', | ||
//Other | ||
'Military': 'military', | ||
'Bunker': 'bunker', | ||
'Bridge': 'bridge', | ||
'Construction': 'construction', | ||
'Container': 'container', | ||
'Gatehouse': 'gatehouse', | ||
'Roof': 'roof', | ||
'Ruins': 'ruins', | ||
'Tree house': 'tree_house', | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,33 @@ | ||
import 'package:latlong/latlong.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:osm_api/osm_api.dart' as osm; | ||
import 'package:latlong/latlong.dart'; | ||
import 'package:quiver/core.dart'; | ||
|
||
abstract class Quest { | ||
LatLng position; | ||
|
||
osm.Element element; | ||
LatLng position = LatLng(0,0); | ||
|
||
Quest(this.element); | ||
|
||
Widget icon(); | ||
|
||
String changesetComment(); | ||
|
||
Quest(this.position, this.element); | ||
String question(); | ||
|
||
String getChangesetComment(); | ||
Future<void> solve(osm.Api api, String possibility); | ||
|
||
String getQuestion(); | ||
@override | ||
bool operator ==(Object that) { | ||
return that is Quest && | ||
this.element.type == that.element.type && | ||
this.element.id == that.element.id && | ||
this.question() == that.question(); | ||
} | ||
|
||
List<String> getPossibilities(); | ||
// Inspired by this: https://stackoverflow.com/questions/20577606/whats-a-good-recipe-for-overriding-hashcode-in-dart | ||
@override | ||
int get hashCode { | ||
return hash3(element.type.hashCode, element.id.hashCode, question()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import 'package:osm_api/osm_api.dart'; | ||
import 'package:client/quests/quest.dart'; | ||
|
||
abstract class QuestFinder { | ||
bool applicable(Element e); | ||
Quest construct(Element e); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,70 @@ | ||
import 'package:client/location_handler.dart'; | ||
import 'package:client/login_handler.dart'; | ||
import 'package:client/quests/bench_quest/backrest_bench_quest.dart'; | ||
import 'package:client/quests/quest.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:latlong/latlong.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:osm_api/osm_api.dart' as osm; | ||
|
||
import 'package:client/quests/bench_quests/backrest_bench_quest.dart'; | ||
import 'package:client/quests/building_quests/building_type_quest.dart'; | ||
import 'package:client/quests/quest.dart'; | ||
|
||
class QuestHandler extends ChangeNotifier { | ||
osm.Api api; | ||
|
||
List<Quest> quests = []; | ||
|
||
bool _isBench(osm.Element element) { | ||
return (element.tags.containsKey('amenity') && | ||
element.tags.containsValue('bench')); | ||
} | ||
|
||
bool _hasTagBenchBackrest(osm.Element element) { | ||
return !(element.tags.containsKey('backrest')); | ||
Set<Quest> quests = Set(); | ||
|
||
final finders = [ | ||
BackrestBenchQuestFinder(), | ||
BuildingTypeQuestFinder(), | ||
]; | ||
|
||
Map<int, osm.Element> _nodes = Map(); | ||
|
||
LatLng _position(osm.Element e) { | ||
if (e.isNode) | ||
return LatLng(e.lat, e.lon); | ||
if (e.isWay) { | ||
double latitude = 0, longitude = 0; | ||
e.nodes.forEach((id) { | ||
final n = _nodes[id]; | ||
latitude += n.lat; | ||
longitude += n.lon; | ||
}); | ||
var count = e.nodes.length; | ||
latitude /= count; | ||
longitude /= count; | ||
|
||
print("Calculated pos: ${latitude}:${longitude}"); | ||
return LatLng(latitude, longitude); | ||
} | ||
throw Exception("Only coordinate node and way"); | ||
} | ||
|
||
void getBenchQuests( | ||
// Finding quests within bound | ||
Future<void> loadQuests( | ||
double left, double bottom, double right, double top) async { | ||
api = osm.Api( | ||
'id', osm.Auth.getUnauthorizedClient(), osm.ApiEnv.dev('master')); | ||
|
||
// Fetch elements within bound | ||
List<osm.Element> elements = | ||
(await api.mapByBox(left, bottom, right, top)).elements; | ||
|
||
List<Quest> benchQuests = []; | ||
List<osm.Element> benchElements = elements | ||
.where((element) => _isBench(element)) | ||
.where((element) => _hasTagBenchBackrest(element)) | ||
.toList(); | ||
elements.forEach((e) { if (e.isNode) _nodes[e.id] = e; }); | ||
|
||
benchElements.forEach((element) { | ||
benchQuests | ||
.add(BackrestBenchQuest(LatLng(element.lat, element.lon), element)); | ||
}); | ||
|
||
print(benchElements); | ||
quests.removeWhere((element) => benchQuests.contains(element)); | ||
quests.addAll(benchQuests); | ||
|
||
quests = benchQuests; | ||
elements.forEach((e) => finders.forEach((f) { | ||
if (f.applicable(e)) { | ||
final q = f.construct(e); | ||
if (!quests.contains(q)) { | ||
q.position = _position(e); | ||
quests.add(q); | ||
} | ||
} | ||
})); | ||
|
||
notifyListeners(); | ||
} | ||
|
||
Future<void> answerBenchQuest( | ||
LoginHandler loginHandler, | ||
LocationHandler locationHandler, | ||
QuestHandler questFinder, | ||
BackrestBenchQuest quest, | ||
int possibilityNumber, | ||
) async { | ||
var api = loginHandler.osmApi(); | ||
|
||
int changeSetId = await api.createChangeset(quest.getChangesetComment()); | ||
|
||
// add the new tag to the tag-map | ||
quest.element.tags['backrest'] = | ||
quest.getPossibilities()[possibilityNumber].toString(); | ||
|
||
int nodeId = await api.updateNode( | ||
quest.element.id, | ||
changeSetId, | ||
quest.position.latitude, | ||
quest.position.longitude, | ||
quest.element.version, | ||
quest.element.tags); | ||
|
||
api.closeChangeset(changeSetId); | ||
print('Selected answer: ' + | ||
quest.getPossibilities()[possibilityNumber].toString()); | ||
|
||
questFinder.getBenchQuests( | ||
locationHandler.mapController.bounds.west, | ||
locationHandler.mapController.bounds.south, | ||
locationHandler.mapController.bounds.east, | ||
locationHandler.mapController.bounds.north); | ||
void removeQuest(Quest quest) { | ||
this.quests.remove(quest); | ||
notifyListeners(); | ||
} | ||
} |
Oops, something went wrong.