feat: Voeg map name support toe

This commit is contained in:
2024-06-11 11:32:11 +02:00
parent 9e77f4996e
commit 1326ab92ba
9 changed files with 33 additions and 91 deletions

View File

@@ -44,71 +44,5 @@ replication:{'class': 'org.apache.cassandra.locator.LocalStrategy
replication:{'class': 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '2'}
</Properties>
</schema>
<table id="10" parent="3" name="maps">
<Properties>caching:{&apos;keys&apos;: &apos;ALL&apos;, &apos;rows_per_partition&apos;: &apos;ALL&apos;}
compression:{&apos;sstable_compression&apos;: &apos;org.apache.cassandra.io.compress.LZ4Compressor&apos;}
bloom_filter_fp_chance:0.01
default_time_to_live:0
speculative_retry:99.0PERCENTILE
gc_grace_seconds:864000
max_index_interval:2048
memtable_flush_period_in_ms:0
min_index_interval:128
read_repair_chance:0
crc_check_chance:1
dclocal_read_repair_chance:0
compaction:{&apos;class&apos;: &apos;SizeTieredCompactionStrategy&apos;}
</Properties>
</table>
<table id="11" parent="3" name="routes">
<Properties>caching:{&apos;keys&apos;: &apos;ALL&apos;, &apos;rows_per_partition&apos;: &apos;ALL&apos;}
compression:{&apos;sstable_compression&apos;: &apos;org.apache.cassandra.io.compress.LZ4Compressor&apos;}
bloom_filter_fp_chance:0.01
default_time_to_live:0
speculative_retry:99.0PERCENTILE
gc_grace_seconds:864000
max_index_interval:2048
memtable_flush_period_in_ms:0
min_index_interval:128
read_repair_chance:0
crc_check_chance:1
dclocal_read_repair_chance:0
compaction:{&apos;class&apos;: &apos;SizeTieredCompactionStrategy&apos;}
</Properties>
</table>
<column id="12" parent="10" name="id">
<DasType>uuid|0s</DasType>
<Position>1</Position>
</column>
<column id="13" parent="10" name="version">
<DasType>int|0s</DasType>
<Position>2</Position>
</column>
<column id="14" parent="10" name="date">
<DasType>timestamp|0s</DasType>
<Position>3</Position>
</column>
<column id="15" parent="10" name="objects">
<DasType>text|0s</DasType>
<Position>4</Position>
</column>
<key id="16" parent="10" name="primary key">
<Columns>id
version|ASC
date|ASC
</Columns>
</key>
<column id="17" parent="11" name="id">
<DasType>uuid|0s</DasType>
<Position>1</Position>
</column>
<column id="18" parent="11" name="path">
<DasType>text|0s</DasType>
<Position>2</Position>
</column>
<key id="19" parent="11" name="primary key">
<Columns>id
</Columns>
</key>
</database-model>
</dataSource>

View File

@@ -8,9 +8,12 @@
</component>
<component name="ChangeListManager">
<list default="true" id="79f184c3-e88e-45be-9116-5fa813562754" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/.idea.REST API/.idea/dataSources/469f6bec-f113-4467-9d39-7ac38558045a.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.REST API/.idea/dataSources/469f6bec-f113-4467-9d39-7ac38558045a.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.REST API/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.REST API/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Console/JsonClasses/Database.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Console/JsonClasses/Database.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Console/Program.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Console/Program.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Console/Routes/RouteMap.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Console/Routes/RoutePath.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Console/Routes/RouteDatabase.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Console/Routes/RouteDatabase.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Console/Routes/RoutePath.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Console/Routes/RoutePath.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Console/bin/Debug/net8.0/Console.dll" beforeDir="false" afterPath="$PROJECT_DIR$/Console/bin/Debug/net8.0/Console.dll" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Console/bin/Debug/net8.0/Console.pdb" beforeDir="false" afterPath="$PROJECT_DIR$/Console/bin/Debug/net8.0/Console.pdb" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../Web/src/components/mapCanvas.jsx" beforeDir="false" afterPath="$PROJECT_DIR$/../Web/src/components/mapCanvas.jsx" afterDir="false" />
@@ -120,7 +123,7 @@
<workItem from="1717668473610" duration="971000" />
<workItem from="1717670832494" duration="901000" />
<workItem from="1717673464254" duration="1428000" />
<workItem from="1718093417281" duration="2913000" />
<workItem from="1718093417281" duration="4387000" />
</task>
<servers />
</component>

View File

@@ -6,11 +6,13 @@ public class Data {
public int version;
public string date;
public string id;
public string name;
}
public class RowData {
public string Id;
public int[][] Objects;
public int Version;
public string Name;
public DateTime Date;
}

View File

@@ -40,10 +40,11 @@ internal static class Program {
session.Execute(@"
CREATE TABLE IF NOT EXISTS Roommapper.Maps(
Id uuid,
Objects text,
Version int,
Name text,
Objects text,
Date timestamp,
PRIMARY KEY (Id,Version,Date)
PRIMARY KEY (Id,Name)
)");
session.Execute(@"

View File

@@ -12,13 +12,13 @@ public class RouteDatabase(ISession cassandraSession): IRoute {
/// </summary>
public HttpResponse Get(HttpRequest request) {
try {
// Prepare the select statement based on the given criteria
// If no criteria is given, throw an exception.
// Using a prepare due to the potential of SQL injection when accepting
// any form of user data.
var queries = new Dictionary<string, Func<string, BoundStatement>> {
["id"] = id => cassandraSession.Prepare(@"SELECT * FROM Roommapper.Maps WHERE Id = ?;").Bind(Guid.Parse(id)),
["name"] = name => cassandraSession.Prepare(@"SELECT * FROM Roommapper.Maps WHERE Name = ?;").Bind(name),
["date"] = date => cassandraSession.Prepare(@"SELECT * FROM roommapper.maps WHERE Date = ?;").Bind(DateTime.Parse(date)),
["version"] = version => cassandraSession.Prepare(@"SELECT * FROM roommapper.maps WHERE Version = ?;").Bind(int.Parse(version)),
["all"] = _ => cassandraSession.Prepare(@"SELECT * FROM roommapper.maps;").Bind()
@@ -29,7 +29,7 @@ public class RouteDatabase(ISession cassandraSession): IRoute {
.Select(query => query.Value(request.QueryString[query.Key]))
.FirstOrDefault();
if (selectStatement == null) throw new Exception("No valid search criteria given, give one of (id, date, version).");
if (selectStatement == null) throw new Exception("No valid search criteria given, give one of (id, date, version, name).");
// Execute the query and return all rows in an array
@@ -65,9 +65,9 @@ public class RouteDatabase(ISession cassandraSession): IRoute {
var uuid = Guid.NewGuid();
var insertStatement = cassandraSession.Prepare(@"
INSERT INTO Roommapper.Maps(Id, Date, Version, Objects)
VALUES (?, toTimeStamp(now()), ?, ?);
").Bind(uuid, 1, parsedBody.objects);
INSERT INTO Roommapper.Maps(Id, Name, Date, Version, Objects)
VALUES (?, ?, toTimeStamp(now()), ?, ?);
").Bind(uuid, parsedBody.name, 1, parsedBody.objects);
cassandraSession.Execute(insertStatement);
@@ -126,7 +126,8 @@ public class RouteDatabase(ISession cassandraSession): IRoute {
Id = row.GetValue<Guid>("id").ToString(),
Objects = $"[{row.GetValue<string>("objects")}]".FromJson<int[][]>(),
Version = row.GetValue<int>("version"),
Date = row.GetValue<DateTime>("date")
Date = row.GetValue<DateTime>("date"),
Name = row.GetValue<string>("name")
}).ToList().ToJson();
}
}

View File

@@ -18,6 +18,7 @@ public class RoutePath(ISession cassandraSession): IRoute {
// any form of user data.
var queries = new Dictionary<string, Func<string, BoundStatement>> {
["id"] = id => cassandraSession.Prepare(@"SELECT * FROM Roommapper.Routes WHERE Id = ?;").Bind(Guid.Parse(id)),
["name"] = name => cassandraSession.Prepare(@"SELECT * FROM Roommapper.Routes WHERE Id = ?;").Bind(name)
};
var selectStatement = queries
@@ -25,7 +26,7 @@ public class RoutePath(ISession cassandraSession): IRoute {
.Select(query => query.Value(request.QueryString[query.Key]))
.FirstOrDefault();
if (selectStatement == null) throw new Exception("No valid search criteria given, give one of (id).");
if (selectStatement == null) throw new Exception("No valid search criteria given, give one of (id, name).");
// Execute the query and return all rows in an array
var rowSet = cassandraSession.Execute(selectStatement);

View File

@@ -15,8 +15,8 @@ export default class MapCanvas extends React.Component {
// Get a reference to the canvas element so we can draw on it
this.canvasRef = React.createRef();
this.state = {
inputValue: '8a97354d-d4ac-43c6-8b32-528cc24e3ede',
searchOption: 'id',
inputValue: '',
searchOption: 'name',
canvasWidth: props.width || this.defaultWidth,
canvasHeight: props.height || this.defaultHeight,
};
@@ -33,16 +33,18 @@ export default class MapCanvas extends React.Component {
this.draw();
}
async getLinePoints(endpoint = '') {
async getLinePoints(endpoint = '', altKey, altVal) {
try {
const { searchOption, inputValue } = this.state;
const url = `${API_ENDPOINT}/database/${endpoint}?${searchOption}=${inputValue}`;
const key = altKey || this.state.searchOption;
const val = altVal || this.state.inputValue;
const url = `${API_ENDPOINT}/database/${endpoint}?${key}=${val}`;
const data = await (await fetch(url)).json();
// Combine all found sets into a singular array.
const map = [];
const map = { 'id': data.length < 2 ? data[0].Id : undefined, 'points': [] };
if (!Array.isArray(data) || data.length < 1) return map;
data.forEach((set) => set.Objects.forEach((coord) => map.push(coord)));
data.forEach((set) => set.Objects.forEach((coord) => map.points.push(coord)));
return map;
} catch (ex) {
@@ -55,9 +57,8 @@ export default class MapCanvas extends React.Component {
// Get the 2D context from the canvas element
const ctx = this.canvasRef.current.getContext('2d');
// Get the points to draw from the server
const points = await this.getLinePoints();
const route = await this.getLinePoints("path");
// const route = await this.getRoutePoints();
const map = await this.getLinePoints();
const route = await this.getLinePoints('path', 'id', map ? map.id : '');
// Set the font for the text we will draw on the canvas
ctx.font = "24px Comic Sans MS";
@@ -66,7 +67,7 @@ export default class MapCanvas extends React.Component {
ctx.clearRect(0, 0, this.state.canvasWidth, this.state.canvasHeight);
// If there are no points, display a message and return
if (!points || points.length < 1) {
if (!map || map.points.length < 1) {
ctx.fillText("No valid entry found.", 10, this.state.canvasHeight / 2);
return;
}
@@ -74,14 +75,14 @@ export default class MapCanvas extends React.Component {
// Loop trough all coordinates, draw a dot at each point to form a top-down
// view of the objects.
ctx.fillStyle = "#000";
points.forEach(point => {
map.points.forEach(point => {
ctx.beginPath();
ctx.arc(point[1], point[0], 1, 0, 2 * Math.PI);
ctx.fill();
});
ctx.fillStyle = "#800000";
route.forEach(point => {
route.points.forEach(point => {
ctx.beginPath();
ctx.arc(point[1], point[0], 1, 0, 2 * Math.PI);
ctx.fill();
@@ -99,9 +100,8 @@ export default class MapCanvas extends React.Component {
value={searchOption}
onChange={(val) => this.setState({ searchOption: val })}
>
<Select value="name">Name</Select>
<Select value="id">ID</Select>
<Select value="version">Version</Select>
<Select value="date">Date</Select>
<Select value="all">All</Select>
</Select>
<Input