@maplat/transform
Version:
A JavaScript library that performs coordinate transformation between two plane coordinate systems using transformation definitions generated by Maplat.
171 lines (165 loc) • 5.26 kB
text/typescript
import { polygon } from "@turf/turf";
import type { Position } from "geojson";
import { PropertyTriKey, Tri, Tins } from "./geometry.ts";
/**
* 三角形の頂点の順序を修正する
* 地図外郭の頂点を含む三角形について、頂点の順序を統一する
* @param tins 三角形群
* @returns 頂点順序が修正された三角形群
*/
function rotateVerticesTriangle(tins: Tins): Tins {
const features = tins.features;
for (let i = 0; i < features.length; i++) {
const feature = features[i];
if (
`${feature.properties!.a.index}`.substring(0, 1) === "b" &&
`${feature.properties!.b.index}`.substring(0, 1) === "b"
) {
features[i] = {
geometry: {
type: "Polygon",
coordinates: [
[
feature.geometry!.coordinates[0][2],
feature.geometry!.coordinates[0][0],
feature.geometry!.coordinates[0][1],
feature.geometry!.coordinates[0][2]
]
]
},
properties: {
a: {
geom: feature.properties!.c.geom,
index: feature.properties!.c.index
},
b: {
geom: feature.properties!.a.geom,
index: feature.properties!.a.index
},
c: {
geom: feature.properties!.b.geom,
index: feature.properties!.b.index
}
},
type: "Feature"
};
} else if (
`${feature.properties!.c.index}`.substring(0, 1) === "b" &&
`${feature.properties!.a.index}`.substring(0, 1) === "b"
) {
features[i] = {
geometry: {
type: "Polygon",
coordinates: [
[
feature.geometry!.coordinates[0][1],
feature.geometry!.coordinates[0][2],
feature.geometry!.coordinates[0][0],
feature.geometry!.coordinates[0][1]
]
]
},
properties: {
a: {
geom: feature.properties!.b.geom,
index: feature.properties!.b.index
},
b: {
geom: feature.properties!.c.geom,
index: feature.properties!.c.index
},
c: {
geom: feature.properties!.a.geom,
index: feature.properties!.a.index
}
},
type: "Feature"
};
}
}
return tins;
}
/**
* 三角形の頂点の座標系を反転する
* @param tri 元の三角形
* @returns 座標系が反転された三角形
*/
function counterTri(tri: Tri): Tri {
const coordinates = (["a", "b", "c", "a"] as PropertyTriKey[]).map(
key => tri.properties![key].geom
);
const geoms = tri.geometry!.coordinates[0];
const props = tri.properties!;
const properties = {
a: { geom: geoms[0], index: props["a"].index },
b: { geom: geoms[1], index: props["b"].index },
c: { geom: geoms[2], index: props["c"].index }
};
return polygon([coordinates], properties);
}
/**
* 頂点座標群から三角形を生成する
* @param points 頂点座標群 [座標, インデックス][]
* @returns 生成された三角形
*/
function buildTri(points: [Position[], string | number][]): Tri {
const coordinates = [0, 1, 2, 0].map(i => points[i][0][0]);
const properties = {
a: { geom: points[0][0][1], index: points[0][1] },
b: { geom: points[1][0][1], index: points[1][1] },
c: { geom: points[2][0][1], index: points[2][1] }
};
return polygon([coordinates], properties);
}
/**
* インデックス配列から三角形を生成する
* @param indexes インデックス配列
* @param points 点群座標
* @param edgeNodes エッジノード座標
* @param cent 重心座標
* @param bboxes バウンディングボックス座標
* @param bakw 座標系を反転するかどうか
* @param version バージョン番号(オプション)
* @returns 生成された三角形
*/
function indexesToTri(
indexes: (number | string)[],
points: Position[][],
edgeNodes: Position[][],
cent: Position[],
bboxes: Position[][],
bakw = false,
version?: number
): Tri {
const points_: [Position[], string | number][] = indexes.map(
(index: number | string) => {
if (!version || version < 2.00703) index = normalizeNodeKey(index);
const point_base = isFinite(index as number)
? points[index as number]
: index === "c"
? cent
: (function () {
const bMatch = (index as string).match(/^b(\d+)$/);
if (bMatch) return bboxes[parseInt(bMatch[1])];
const eMatch = (index as string).match(/^e(\d+)$/);
if (eMatch) return edgeNodes[parseInt(eMatch[1])];
throw new Error("Bad index value for indexesToTri");
})();
return bakw
? [[point_base![1], point_base![0]], index]
: [[point_base![0], point_base![1]], index];
}
);
return buildTri(points_);
}
// After 7.0.3 Normalizing node index key
function normalizeNodeKey(index: number | string) {
if (typeof index === "number") return index;
return index.replace(/^(c|e|b)(?:ent|dgeNode|box)(\d+)?$/, "$1$2");
}
export {
rotateVerticesTriangle,
counterTri,
indexesToTri,
normalizeNodeKey
};