function findCrossingsByWay(way1, graph, tree) {
        var edgeCrossInfos = [];
        if (way1.type !== 'way') return edgeCrossInfos;

        var taggedFeature1 = getFeatureWithFeatureTypeTagsForWay(way1, graph);
        var way1FeatureType = getFeatureType(taggedFeature1, graph);
        if (way1FeatureType === null) return edgeCrossInfos;

        var checkedSingleCrossingWays = {};

        // declare vars ahead of time to reduce garbage collection
        var i, j;
        var extent;
        var n1, n2, nA, nB, nAId, nBId;
        var segment1, segment2;
        var oneOnly;
        var segmentInfos, segment2Info, way2, taggedFeature2, way2FeatureType;
        var way1Nodes = graph.childNodes(way1);
        var comparedWays = {};
        for (i = 0; i < way1Nodes.length - 1; i++) {
            n1 = way1Nodes[i];
            n2 = way1Nodes[i + 1];
            extent = geoExtent([
                [
                    Math.min(n1.loc[0], n2.loc[0]),
                    Math.min(n1.loc[1], n2.loc[1])
                ],
                [
                    Math.max(n1.loc[0], n2.loc[0]),
                    Math.max(n1.loc[1], n2.loc[1])
                ]
            ]);

            // Optimize by only checking overlapping segments, not every segment
            // of overlapping ways
            segmentInfos = tree.waySegments(extent, graph);

            for (j = 0; j < segmentInfos.length; j++) {
                segment2Info = segmentInfos[j];

                // don't check for self-intersection in this validation
                if (segment2Info.wayId === way1.id) continue;

                // skip if this way was already checked and only one issue is needed
                if (checkedSingleCrossingWays[segment2Info.wayId]) continue;

                // mark this way as checked even if there are no crossings
                comparedWays[segment2Info.wayId] = true;

                way2 = graph.hasEntity(segment2Info.wayId);
                if (!way2) continue;
                taggedFeature2 = getFeatureWithFeatureTypeTagsForWay(way2, graph);
                // only check crossing highway, waterway, building, and railway
                way2FeatureType = getFeatureType(taggedFeature2, graph);

                if (way2FeatureType === null ||
                    isLegitCrossing(taggedFeature1.tags, way1FeatureType, taggedFeature2.tags, way2FeatureType)) {
                    continue;
                }

                // create only one issue for building crossings
                oneOnly = way1FeatureType === 'building' || way2FeatureType === 'building';

                nAId = segment2Info.nodes[0];
                nBId = segment2Info.nodes[1];
                if (nAId === n1.id || nAId === n2.id ||
                    nBId === n1.id || nBId === n2.id) {
                    // n1 or n2 is a connection node; skip
                    continue;
                }
                nA = graph.hasEntity(nAId);
                if (!nA) continue;
                nB = graph.hasEntity(nBId);
                if (!nB) continue;

                segment1 = [n1.loc, n2.loc];
                segment2 = [nA.loc, nB.loc];
                var point = geoLineIntersection(segment1, segment2);
                if (point) {
                    edgeCrossInfos.push({
                        wayInfos: [
                            {
                                way: way1,
                                featureType: way1FeatureType,
                                edge: [n1.id, n2.id]
                            },
                            {
                                way: way2,
                                featureType: way2FeatureType,
                                edge: [nA.id, nB.id]
                            }
                        ],
                        crossPoint: point
                    });
                    if (oneOnly) {
                        checkedSingleCrossingWays[way2.id] = true;
                        break;
                    }
                }
            }
        }
        return edgeCrossInfos;
    }
@typedef {NonNullable<ReturnType<getFeatureType>>} FeatureType
@type {`${FeatureType}-${FeatureType}`}