Skip to content

Four Remaining Questions #32

@taibeled

Description

@taibeled

There are now only five questions left! That is, questions with clear icons. Unfortunately, the remaining questions are all difficult to implement. The remaining questions can all be put into three categories:

Easy to implement badly

In #28, I first attempted to attack the difficult measuring questions. These questions have so many nodes that doing the naive buffer strategy takes way too long. I was able to salvage those questions by making them end-game exclusive (mostly). This could be easily done with the two questions in this category: distance to Shinkansen and distance to body of water. However, those questions scopes aren't exclusive to the endgame. I have spent a while attempting to implement the measuring to high-speed train (Shinkansen) question, however, no matter what combination of simplifications, combines, buffers, and intersections, it would invariably crash the tab. Although I have not yet attacked body of water, in areas like Japan, it would almost certainly have a similar fate to that of high-speed train. Implementing these two questions would either require the solution from #28, which would make the seekers job more strenuous, or a lot of optimizations.

Line Voronoi

As I found out with the distance to Shinkansen question, Open Street Map likes to fragment its ways and relations into numerous chunks, each with slightly different properties. That's the first part of these questions, determining what line each way is part of. I wrote some somewhat efficient code for that:

const groupObjects = (objects: any[]): any[][] => {
    const filteredObjects = objects.filter(
        (obj) =>
            obj.properties.name !== undefined ||
            obj.properties["name:en"] !== undefined ||
            obj.properties.network !== undefined,
    );

    const n = filteredObjects.length;
    const parent: number[] = Array.from({ length: n }, (_, i) => i);

    const find = (i: number): number => {
        if (parent[i] !== i) {
            parent[i] = find(parent[i]);
        }
        return parent[i];
    };

    const union = (i: number, j: number): void => {
        const rootI = find(i);
        const rootJ = find(j);
        if (rootI !== rootJ) {
            parent[rootJ] = rootI;
        }
    };

    const keys = ["name", "name:en", "network"];
    const paramMap: Record<string, number> = {};

    for (let i = 0; i < n; i++) {
        const obj = filteredObjects[i];
        for (const key of keys) {
            const value = obj.properties[key];
            if (value !== undefined) {
                const mapKey = `${key}:${value}`;
                if (paramMap[mapKey] === undefined) {
                    paramMap[mapKey] = i;
                } else {
                    union(i, paramMap[mapKey]);
                }
            }
        }
    }

    const groups: Record<number, any[]> = {};
    for (let i = 0; i < n; i++) {
        const root = find(i);
        if (!groups[root]) {
            groups[root] = [];
        }
        groups[root].push(filteredObjects[i]);
    }
    return Object.values(groups);
};

As you might be able to deduce from the talk about ways, the two questions in this category are the tentacles metro line and matching Shinkansen question. Once the exact lines are found, the Voronoi polygons have to be found. However, these aren't points but a sequence of line segments (technically a sequence of great circle arcs, but I already spent five hours solving that 1c80a33). My naive thought was to perform the geoSpatialVoronoi on each coordinate in each way and then connect the Voronoi polygons forming a larger Voronoi polygon. The algorithm 1500ms for a 15 mile tentacles centered in Tokyo. I didn't have much success actually combining the Voronoi polygons, though. Furthermore, although 1500ms is fine on a desktop, in a scenario where someone was actually using this, on their phone, it would surely take much longer. Adding these questions are like adding the questions from the last category with an added hinderance.

Elevation

This category is the outlier compared to the above categories. It only contains the distance from sea level question. That question is very different from all the other questions added to the application. First off, OSM does not contain elevation. Therefore, the only approach I can envision is taking a database of rough elevations for given latitudes and longitudes and eliminating off that. Lots of eliminations is the problem from the first heading, so this would also probably be difficult. This is the only question, besides distance to body of water, that I have yet to try to complete.

Metadata

Metadata

Assignees

No one assigned

    Labels

    game-questionAn issue regarding the adding of a question

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions