Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema #100

Merged
merged 1 commit into from
Nov 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 124 additions & 8 deletions lib/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21730,6 +21730,122 @@ Object {
}
`;

exports[`toGeoJSON schema.kml 1`] = `
Object {
"features": Array [
Object {
"geometry": Object {
"coordinates": Array [
Array [
Array [
12.8206124,
55.9654246,
],
Array [
12.8204862,
55.9654342,
],
Array [
12.8204902,
55.9654507,
],
Array [
12.8206164,
55.9654411,
],
Array [
12.8206124,
55.9654246,
],
],
],
"type": "Polygon",
},
"properties": Object {
"block_block_number": 1,
"cn_cv_1109": "89%",
"fill-opacity": 0,
"gid": 167001,
"plotno_plot_number": 167001,
"random": 0.9,
"random_2": 0.4,
"random_2_block": 41,
"random_2_trial": 39,
"random_block": 98,
"random_trial": 96,
"stroke": "#ff0000",
"stroke-opacity": 1,
"tream_treatment_number": "16",
},
"type": "Feature",
},
],
"type": "FeatureCollection",
}
`;

exports[`toGeoJSON schema.kml 2`] = `
Object {
"children": Array [
Object {
"children": Array [
Object {
"geometry": Object {
"coordinates": Array [
Array [
Array [
12.8206124,
55.9654246,
],
Array [
12.8204862,
55.9654342,
],
Array [
12.8204902,
55.9654507,
],
Array [
12.8206164,
55.9654411,
],
Array [
12.8206124,
55.9654246,
],
],
],
"type": "Polygon",
},
"properties": Object {
"block_block_number": 1,
"cn_cv_1109": "89%",
"fill-opacity": 0,
"gid": 167001,
"plotno_plot_number": 167001,
"random": 0.9,
"random_2": 0.4,
"random_2_block": 41,
"random_2_trial": 39,
"random_block": 98,
"random_trial": 96,
"stroke": "#ff0000",
"stroke-opacity": 1,
"tream_treatment_number": "16",
},
"type": "Feature",
},
],
"meta": Object {
"name": "TES_124_167_28_JUL_2022_1109",
},
"type": "folder",
},
],
"type": "root",
}
`;

exports[`toGeoJSON selfclosing.kml 1`] = `
Object {
"features": Array [
Expand Down Expand Up @@ -21772,9 +21888,9 @@ Object {
"type": "Point",
},
"properties": Object {
"ElevationGain": "10",
"ElevationGain": 10,
"TrailHeadName": "Pi in the sky",
"TrailLength": "3.14159",
"TrailLength": 3.14159,
"name": "Easy trail",
"styleUrl": "#trailhead-balloon-template",
},
Expand All @@ -21789,9 +21905,9 @@ Object {
"type": "Point",
},
"properties": Object {
"ElevationGain": "10000",
"ElevationGain": 10000,
"TrailHeadName": "Mount Everest",
"TrailLength": "347.45",
"TrailLength": 347.45,
"name": "Difficult trail",
"styleUrl": "#trailhead-balloon-template",
},
Expand All @@ -21814,9 +21930,9 @@ Object {
"type": "Point",
},
"properties": Object {
"ElevationGain": "10",
"ElevationGain": 10,
"TrailHeadName": "Pi in the sky",
"TrailLength": "3.14159",
"TrailLength": 3.14159,
"name": "Easy trail",
"styleUrl": "#trailhead-balloon-template",
},
Expand All @@ -21831,9 +21947,9 @@ Object {
"type": "Point",
},
"properties": Object {
"ElevationGain": "10000",
"ElevationGain": 10000,
"TrailHeadName": "Mount Everest",
"TrailLength": "347.45",
"TrailLength": 347.45,
"name": "Difficult trail",
"styleUrl": "#trailhead-balloon-template",
},
Expand Down
21 changes: 17 additions & 4 deletions lib/kml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
isElement,
normalizeId,
} from "./shared";
import { Schema, typeConverters } from "./kml/shared";

/**
* A folder including metadata. Folders
Expand Down Expand Up @@ -78,6 +79,16 @@ function buildStyleMap(node: Document): StyleMap {
return styleMap;
}

function buildSchema(node: Document): Schema {
const schema: Schema = {};
for (const field of $(node, "SimpleField")) {
schema[field.getAttribute("name") || ""] =
typeConverters[field.getAttribute("type") || ""] ||
typeConverters["string"];
}
return schema;
}

const FOLDER_PROPS = [
"name",
"visibility",
Expand Down Expand Up @@ -146,6 +157,7 @@ function getFolder(node: Element): Folder {
*/
export function kmlWithFolders(node: Document): Root {
const styleMap = buildStyleMap(node);
const schema = buildSchema(node);

// atomic geospatial types supported by KML - MultiGeometry is
// handled separately
Expand All @@ -161,15 +173,15 @@ export function kmlWithFolders(node: Document): Root {
switch (node.tagName) {
case "GroundOverlay": {
placemarks.push(node);
const placemark = getGroundOverlay(node, styleMap);
const placemark = getGroundOverlay(node, styleMap, schema);
if (placemark) {
pointer.children.push(placemark);
}
break;
}
case "Placemark": {
placemarks.push(node);
const placemark = getPlacemark(node, styleMap);
const placemark = getPlacemark(node, styleMap, schema);
if (placemark) {
pointer.children.push(placemark);
}
Expand Down Expand Up @@ -203,12 +215,13 @@ export function kmlWithFolders(node: Document): Root {
*/
export function* kmlGen(node: Document): Generator<F> {
const styleMap = buildStyleMap(node);
const schema = buildSchema(node);
for (const placemark of $(node, "Placemark")) {
const feature = getPlacemark(placemark, styleMap);
const feature = getPlacemark(placemark, styleMap, schema);
if (feature) yield feature;
}
for (const groundOverlay of $(node, "GroundOverlay")) {
const feature = getGroundOverlay(groundOverlay, styleMap);
const feature = getGroundOverlay(groundOverlay, styleMap, schema);
if (feature) yield feature;
}
}
Expand Down
6 changes: 4 additions & 2 deletions lib/kml/ground_overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
extractTimeSpan,
extractTimeStamp,
getMaybeHTMLDescription,
Schema,
} from "./shared";
import { extractIconHref, extractStyle } from "./extractStyle";
import { coord, fixRing, getCoordinates } from "./geometry";
Expand Down Expand Up @@ -91,7 +92,8 @@ function getLatLonBox(node: Element): Polygon | null {

export function getGroundOverlay(
node: Element,
styleMap: StyleMap
styleMap: StyleMap,
schema: Schema
): Feature<Polygon | null> {
const geometry = getGroundOverlayBox(node);

Expand All @@ -116,7 +118,7 @@ export function getGroundOverlay(
extractCascadedStyle(node, styleMap),
extractStyle(node),
extractIconHref(node),
extractExtendedData(node),
extractExtendedData(node, schema),
extractTimeSpan(node),
extractTimeStamp(node)
),
Expand Down
6 changes: 4 additions & 2 deletions lib/kml/placemark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
extractTimeSpan,
extractTimeStamp,
getMaybeHTMLDescription,
Schema,
} from "./shared";
import { extractStyle } from "./extractStyle";
import { getGeometry } from "./geometry";
Expand All @@ -23,7 +24,8 @@ function geometryListToGeometry(geometries: Geometry[]): Geometry | null {

export function getPlacemark(
node: Element,
styleMap: StyleMap
styleMap: StyleMap,
schema: Schema
): Feature<Geometry | null> {
const { coordTimes, geometries } = getGeometry(node);

Expand All @@ -42,7 +44,7 @@ export function getPlacemark(
getMaybeHTMLDescription(node),
extractCascadedStyle(node, styleMap),
extractStyle(node),
extractExtendedData(node),
extractExtendedData(node, schema),
extractTimeSpan(node),
extractTimeStamp(node),
coordTimes.length
Expand Down
21 changes: 19 additions & 2 deletions lib/kml/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,32 @@ import {
val1,
} from "../shared";

export function extractExtendedData(node: Element) {
export type TypeConverter = (x: string) => unknown;
export type Schema = { [key: string]: TypeConverter };

const toNumber: TypeConverter = (x) => Number(x);
export const typeConverters: Record<string, TypeConverter> = {
string: (x) => x,
int: toNumber,
uint: toNumber,
short: toNumber,
ushort: toNumber,
float: toNumber,
double: toNumber,
bool: (x) => Boolean(x),
};

export function extractExtendedData(node: Element, schema: Schema) {
return get(node, "ExtendedData", (extendedData, properties) => {
for (const data of $(extendedData, "Data")) {
properties[data.getAttribute("name") || ""] = nodeVal(
get1(data, "value")
);
}
for (const simpleData of $(extendedData, "SimpleData")) {
properties[simpleData.getAttribute("name") || ""] = nodeVal(simpleData);
const name = simpleData.getAttribute("name") || "";
const typeConverter = schema[name] || typeConverters.string;
properties[name] = typeConverter(nodeVal(simpleData));
}
return properties;
});
Expand Down
53 changes: 53 additions & 0 deletions test/data/schema.kml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="TES_124_167_28_JUL_2022_1109" id="TES_124_167_28_JUL_2022_1109">
<SimpleField name="gid" type="float"></SimpleField>
<SimpleField name="plotno_plot_number" type="float"></SimpleField>
<SimpleField name="tream_treatment_number" type="string"></SimpleField>
<SimpleField name="block_block_number" type="float"></SimpleField>
<SimpleField name="random" type="float"></SimpleField>
<SimpleField name="random_2" type="float"></SimpleField>
<SimpleField name="random_trial" type="int"></SimpleField>
<SimpleField name="random_2_trial" type="int"></SimpleField>
<SimpleField name="random_block" type="int"></SimpleField>
<SimpleField name="random_2_block" type="int"></SimpleField>
<SimpleField name="cn_cv_1109" type="string"></SimpleField>
</Schema>
<Folder>
<name>TES_124_167_28_JUL_2022_1109</name>
<Placemark>
<Style>
<LineStyle>
<color>ff0000ff</color>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<ExtendedData>
<SchemaData schemaUrl="#TES_124_167_28_JUL_2022_1109">
<SimpleData name="gid">167001</SimpleData>
<SimpleData name="plotno_plot_number">167001</SimpleData>
<SimpleData name="tream_treatment_number">16</SimpleData>
<SimpleData name="block_block_number">1</SimpleData>
<SimpleData name="random">0.9</SimpleData>
<SimpleData name="random_2">0.4</SimpleData>
<SimpleData name="random_trial">96</SimpleData>
<SimpleData name="random_2_trial">39</SimpleData>
<SimpleData name="random_block">98</SimpleData>
<SimpleData name="random_2_block">41</SimpleData>
<SimpleData name="cn_cv_1109">89%</SimpleData>
</SchemaData>
</ExtendedData>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>12.8206124,55.9654246 12.8204862,55.9654342 12.8204902,55.9654507 12.8206164,55.9654411 12.8206124,55.9654246</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Folder>
</Document>
</kml>