Skip to content

Commit

Permalink
Add support for Schema tag and convert properties to correct datatype
Browse files Browse the repository at this point in the history
- Fixes #69.
  • Loading branch information
perliedman authored and tmcw committed Nov 12, 2022
1 parent 1905db4 commit adb8ec7
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 18 deletions.
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>

0 comments on commit adb8ec7

Please sign in to comment.