Skip to content

Commit

Permalink
Implement address-search and save/load
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSaminator committed Oct 7, 2023
1 parent 8bfa34f commit 228cf20
Show file tree
Hide file tree
Showing 9 changed files with 536 additions and 9 deletions.
115 changes: 115 additions & 0 deletions AppMode/AddPlaceToListByAddress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using System.Xml;
using FancyMapSnapper.Mapping;
using FancyMapSnapper.Ui;
using FancyMapSnapper.Ui.Widgets;
using SkiaSharp;

namespace FancyMapSnapper.AppMode;

public class AddPlaceToListByAddress : ApplicationMode {
private readonly List<string> _places;

public AddPlaceToListByAddress(List<string> places) {
_places = places;
}

private readonly UiInputField _houseNum = new() { Size = new SKRect(400, 386, 584, 434) };
private readonly UiInputField _streetName = new() { Size = new SKRect(616, 386, 1200, 434) };
private readonly UiInputField _city = new() { Size = new SKRect(400, 466, 784, 514) };
private readonly UiInputField _state = new() { Size = new SKRect(816, 466, 984, 514) };
private readonly UiInputField _postCode = new() { Size = new SKRect(1016, 466, 1200, 514) };

private readonly UiButton _add = new() { Size = new SKRect(500, 600, 784, 648), Text = "Add" };
private readonly UiButton _cancel = new() { Size = new SKRect(816, 600, 1100, 648), Text = "Cancel" };

private readonly UiRoot _ui = new();

private static async Task<List<string>?> PerformAddressQuery(string houseNum, string streetName, string city, string state, string postCode) {
var taskResult = await XmlHelper.ConstructOsmQuery(
(scriptDoc, osmScript) => scriptDoc.AddressQuery(osmScript, houseNum, streetName, city, state, postCode)
).GetPlaceXml();

var osmRoot = taskResult["osm"];
if (osmRoot == null) {
Console.WriteLine($"Got error document: {taskResult.ToXmlString()}");
return null;
}

// Clear out extra stuff that we don't need
var noteElement = osmRoot["note"];
if (noteElement != null) osmRoot.RemoveChild(noteElement);

var metaElement = osmRoot["meta"];
if (metaElement != null) osmRoot.RemoveChild(metaElement);

List<string> places = new();
foreach (var wayObj in osmRoot.GetElementsByTagName("way")) {
var wayElement = (XmlElement)wayObj;

var id = wayElement.GetAttribute("id");
string? name = null;
foreach (var tagObj in wayElement.GetElementsByTagName("tag")) {
var tagElement = (XmlElement)tagObj;
if (tagElement.GetAttribute("k") == "name")
name = tagElement.GetAttribute("v");
}

if (name == null)
places.Add("id:" + id);
else
places.Add(name);
}

return places;
}

private void AddFromAddress() {
_add.IsEnabled = false;
_cancel.IsEnabled = false;

PerformAddressQuery(
_houseNum.Builder.ToString(),
_streetName.Builder.ToString(),
_city.Builder.ToString(),
_state.Builder.ToString(),
_postCode.Builder.ToString()
).ContinueWith(task => {
var taskResult = task.Result;
FmsApp.Instance.PostAction(() => {
var places = _places.ToList();
if (taskResult != null)
places.AddRange(taskResult);
_next = new InitialPlaceListBuilding(places);
});
});
}

private void Cancel() {
_next = new InitialPlaceListBuilding(_places);
}

public override void Initialize() {
_add.OnClick += AddFromAddress;
_cancel.OnClick += Cancel;

_ui.AddChild(_houseNum);
_ui.AddChild(_streetName);
_ui.AddChild(_city);
_ui.AddChild(_state);
_ui.AddChild(_postCode);
_ui.AddChild(_add);
_ui.AddChild(_cancel);
}

public override void HandleInput(in InputEvent input) {
_ui.HandleInput(in input);
}

public override void Render(SKCanvas canvas) {
_ui.Tick();
_ui.Render(canvas);
}

private ApplicationMode? _next;
public override ApplicationMode NextMode => _next ?? this;
}
13 changes: 10 additions & 3 deletions AppMode/CustomizingMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ public CustomizingMap(List<string> places, OsmQueryResult queryResult) {
private readonly UiScrollPane _toggles = new() { OuterSize = new SKRect(1200, 160, 1584, 820) };
private readonly Dictionary<RadioButtonGroup, List<OsmWay>> _associatedWays = new();

private readonly UiButton _exportMap = new() { Size = new SKRect(1216, 836, 1392, 884), Text = "Export" };
private readonly UiButton _closeMap = new() { Size = new SKRect(1408, 836, 1584, 884), Text = "Close" };
private readonly UiButton _saveMap = new() { Size = new SKRect(1216, 836, 1328, 884), Text = "Save", FontSize = 20 };
private readonly UiButton _exportMap = new() { Size = new SKRect(1344, 836, 1456, 884), Text = "Export", FontSize = 20 };
private readonly UiButton _closeMap = new() { Size = new SKRect(1472, 836, 1584, 884), Text = "Close", FontSize = 20 };

private void RepopulateBBox() {
_next = new LoadingOsmData(_places, in _queryResult.BBox);
Expand All @@ -59,7 +60,7 @@ private void RepopulateBBox() {
private void AddNewMapObject(StringBuilder name) {
var inputText = name.ToString();
if (inputText.StartsWith("UH "))
inputText = "University Hospitals " + inputText[3..];
inputText = "University Hospitals " + inputText["UH ".Length..];
_next = new LoadingOsmData(_places, new List<string> { inputText }, _queryResult);
}

Expand Down Expand Up @@ -164,6 +165,10 @@ private static double GetTextScaling(OsmQueryResult result, in SKRect targetRect
private static readonly Lazy<DirectoryInfo> ExportDirLazy = new(() => Directory.Exists("exports") ? new DirectoryInfo("exports") : Directory.CreateDirectory("exports"));
private static DirectoryInfo ExportDir => ExportDirLazy.Value;

private void SaveMap() {
_next = new SavingMap(_places, _queryResult);
}

private void ExportMap() {
var bboxWidth = _queryResult.BBox.XMax - _queryResult.BBox.XMin;
var bboxHeight = _queryResult.BBox.YMax - _queryResult.BBox.YMin;
Expand Down Expand Up @@ -381,9 +386,11 @@ ref y
ref y
);

_ui.AddChild(_saveMap);
_ui.AddChild(_exportMap);
_ui.AddChild(_closeMap);

_saveMap.OnClick += SaveMap;
_exportMap.OnClick += ExportMap;
_closeMap.OnClick += CloseMap;
}
Expand Down
54 changes: 49 additions & 5 deletions AppMode/InitialPlaceListBuilding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,31 @@ public InitialPlaceListBuilding(List<string> places) {
private readonly UiScrollPane _inputs = new() { OuterSize = new SKRect(400, 200, 1200, 640) };

private readonly UiButton _addButton = new() {
Size = new SKRect(400, 672, 784, 720),
Size = new SKRect(400, 672, 584, 720),
IsEnabled = true,
Text = "+"
};

private readonly UiButton _byAddressButton = new() {
Size = new SKRect(616, 672, 984, 720),
IsEnabled = true,
Text = "By Address"
};

private readonly UiButton _removeButton = new() {
Size = new SKRect(816, 672, 1200, 720),
Size = new SKRect(1016, 672, 1200, 720),
IsEnabled = false,
Text = "-"
};

private readonly UiButton _loadButton = new() {
Size = new SKRect(400, 752, 784, 800),
IsEnabled = true,
Text = "Load Map"
};

private readonly UiButton _doneButton = new() {
Size = new SKRect(608, 752, 992, 800),
Size = new SKRect(816, 752, 1200, 800),
IsEnabled = false,
Text = "Build Map"
};
Expand Down Expand Up @@ -118,7 +130,29 @@ private void RemoveInputAtEnd() {
moveDownButton.IsEnabled = false;
}

private void DoneListing() {
private void GetByAddress() {
_next = new AddPlaceToListByAddress(GetPlaces());
}

private void LoadMap() {
var places = new List<string>();

for (var i = 0; i < _inputs.NumChildren; i++) {
var group = (UiGroup)_inputs.ChildAt(i);
var input = (UiInputField)group.ChildAt(0);
var inputText = input.Builder.ToString();
if (string.IsNullOrWhiteSpace(inputText)) continue;

// Special case: abbreviating University Hospitals as UH
if (inputText.StartsWith("UH "))
inputText = "University Hospitals " + inputText["UH ".Length..];
places.Add(inputText);
}

_next = new LoadingMap(places);
}

private List<string> GetPlaces() {
var places = new List<string>();

for (var i = 0; i < _inputs.NumChildren; i++) {
Expand All @@ -129,10 +163,16 @@ private void DoneListing() {

// Special case: abbreviating University Hospitals as UH
if (inputText.StartsWith("UH "))
inputText = "University Hospitals " + inputText[3..];
inputText = "University Hospitals " + inputText["UH ".Length..];
places.Add(inputText);
}

return places;
}

private void DoneListing() {
var places = GetPlaces();

if (places.Count > 0) {
_next = new LoadingOsmData(places);
}
Expand All @@ -142,11 +182,15 @@ public override void Initialize() {
_ui.AddChild(_inputs);

_addButton.OnClick += AddInputAtEnd;
_byAddressButton.OnClick += GetByAddress;
_removeButton.OnClick += RemoveInputAtEnd;
_loadButton.OnClick += LoadMap;
_doneButton.OnClick += DoneListing;

_ui.AddChild(_addButton);
_ui.AddChild(_byAddressButton);
_ui.AddChild(_removeButton);
_ui.AddChild(_loadButton);
_ui.AddChild(_doneButton);

foreach (var place in _places) {
Expand Down
85 changes: 85 additions & 0 deletions AppMode/LoadingMap.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Xml;
using FancyMapSnapper.Mapping;
using FancyMapSnapper.Ui;
using FancyMapSnapper.Ui.Widgets;
using SkiaSharp;

namespace FancyMapSnapper.AppMode;

public class LoadingMap : ApplicationMode {
private readonly List<string> _places;
private readonly List<string> _saveFiles = new();

public LoadingMap(List<string> places) {
_places = places;

var saves = Directory.CreateDirectory("saves");
foreach (var fileInfo in saves.GetFiles()) {
if (!fileInfo.Name.EndsWith(".xml")) continue;

_saveFiles.Add(fileInfo.Name[..^".xml".Length]);
}
}

private readonly UiRoot _ui = new();

private void Load(string name) {
var saves = Directory.CreateDirectory("saves");
var loadPath = Path.Combine(saves.FullName, name + ".xml");
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(File.ReadAllText(loadPath));
var (places, result) = OsmQueryResult.FromXml(xmlDoc);

_next = new CustomizingMap(places, result);
}

private void Cancel() {
_next = new InitialPlaceListBuilding(_places);
}

private const float InputButtonWidth = 784;
private const float InputButtonHeight = 48;
private const float InputButtonSeparation = 72;

public override void Initialize() {
var scrollPane = new UiScrollPane { OuterSize = new SKRect(400, 200, 1200, 640) };

float y = 0;
foreach (var saveFile in _saveFiles) {
var loadButton = new UiButton {
Text = saveFile,
IsEnabled = true,
Size = new SKRect(0, y + (InputButtonSeparation - InputButtonHeight) / 2, InputButtonWidth, y + (InputButtonSeparation + InputButtonHeight) / 2)
};

loadButton.OnClick += () => Load(saveFile);
scrollPane.AddChild(loadButton);

y += InputButtonSeparation;
}

_ui.AddChild(scrollPane);

var cancelButton = new UiButton {
Text = "Cancel Load",
IsEnabled = true,
Size = new SKRect(400, 640 + (InputButtonSeparation - InputButtonHeight) / 2, 1200, 640 + (InputButtonSeparation + InputButtonHeight) / 2)
};

cancelButton.OnClick += Cancel;

_ui.AddChild(cancelButton);
}

public override void HandleInput(in InputEvent input) {
_ui.HandleInput(in input);
}

public override void Render(SKCanvas canvas) {
_ui.Tick();
_ui.Render(canvas);
}

private ApplicationMode? _next;
public override ApplicationMode NextMode => _next ?? this;
}
Loading

0 comments on commit 228cf20

Please sign in to comment.