UNPKG

gs-modelling

Version:

A set of 3D modelling functions for gs-JSON.

305 lines (288 loc) 11.2 kB
/** * Import geojson files. */ import { writeGsToJSONFile } from "../../libs/filesys/filesys"; import * as gs from "gs-json"; import * as filesys from "../../libs/filesys/filesys"; const path: string = "../gs-modelling/src/assets/geojson/"; /** * Converts multiple geojson files to one gs model. * @param filenames The paths to the file that contains the geojson data. * @returns Model */ export function geojsons(filenames: string[]): gs.IModel { let elevation: number = 0; const model: gs.IModel = new gs.Model(); for (const filename of filenames) { const str_data: string = filesys.readToJSONFile(filename); const obj_data = JSON.parse(str_data); process(model, obj_data, elevation * 20); elevation++; } return model; } /** * Converts geojson to a gs model. * @param filename The path to the file that cntains the geojson data. * @returns Model */ export function geojson(filename: string): gs.IModel { const str_data: string = filesys.readToJSONFile(filename); const obj_data = JSON.parse(str_data); const model: gs.IModel = new gs.Model(); process(model, obj_data, 0); return model; } /** * Converts geojson to a gs model. * @param obj_data The geojson data.. * @returns Model */ export function process(model: gs.IModel, obj_data: any, elevation: number): void { console.log("Number of features = ", obj_data.features.length); // arrays for features const points: any[] = []; const linestrings: any[] = []; const polygons: any[] = []; const polygons_holes: any[] = []; const multipoints: any[] = []; const multilinestrings: any[] = []; const multipolygons: any[] = []; const multipolygons_holes: any[] = []; const others: any[] = []; // map for attributes const attrib_data: Map<string, gs.EDataType> = new Map(); // loop through all features for (const feature of obj_data.features) { // get the attributes const propos: any = feature.properties; for (const key of Object.keys(propos)) { if (!attrib_data.has(key)) { if (isNaN(propos[key])) { attrib_data.set(key, gs.EDataType.type_str); } else { attrib_data.set(key, gs.EDataType.type_num); } } } // get the features switch (feature.geometry.type) { case "Point": points.push(feature); break; case "LineString": linestrings.push(feature); break; case "Polygon": polygons.push(feature); if (feature.geometry.coordinates > 1) { polygons_holes.push(feature); } break; case "MultiPoint": multipoints.push(feature); break; case "MultiLineString": multilinestrings.push(feature); break; case "MultiPolygon": multipolygons.push(feature); let has_holes: boolean = false; for (const face of feature.geometry.coordinates) { if (face.length > 1) {has_holes = true; break;} } if (has_holes) { multipolygons_holes.push(feature); } break; default: others.push(feature); break; } } // log message console.log( "Point: " + points.length + "\n" + "LineString: " + linestrings.length + "\n" + "Polygon: " + polygons.length + "\n" + " Polygon + hole: " + polygons_holes.length + "\n" + "MultiPoint: " + multipoints.length + "\n" + "MultiLineString: " + multilinestrings.length + "\n" + "MultiPolygon: " + multipolygons.length + "\n" + " MultiPolygon + hole: " + multipolygons_holes.length + "\n" + "Other: " + others + "\n\n"); // make geometry in model const attribs: Map<string, gs.IEntAttrib> = add_attribs(attrib_data, model); add_linestrings(linestrings, attribs, model, elevation); add_polygons(polygons, attribs, model, elevation); add_multilinestrings(linestrings, attribs, model, elevation); add_multipolygons(multipolygons, attribs, model, elevation); // log model results console.log(model.toString()); } /** * Adds attributs to the geojson model. * @param attrib_data Attrinute data (name, and data type) * @param model The model * @returns A Map containing the attrib name and the attrib object. */ function add_attribs(attrib_data: Map<string, gs.EDataType>, model: gs.IModel): Map<string, gs.IEntAttrib> { // create polygons // create the attributes const attribs: Map<string, gs.IEntAttrib> = new Map(); for (const [name, data_type] of attrib_data.entries()) { attribs.set(name, model.addEntAttrib(name, gs.EGeomType.objs, data_type)); } return attribs; } /* "geometry": { "type": "LineString", "coordinates": [ [30, 10], [10, 30], [40, 40] ] } */ /** * Adds linestrings to the model * @param linestrings The features to add. * @param model The model */ function add_linestrings(linestrings: any[], attribs: Map<string, gs.IEntAttrib>, model: gs.IModel, elevation: number): void { const geom: gs.IGeom = model.getGeom(); // create polygons for (const linestring of linestrings) { // add geometry, single polyline per feature const points: gs.IPoint[] = geom.addPoints(linestring.geometry.coordinates.map((xy) => [xy[0], xy[1], elevation])); const polyline: gs.IPolymesh = geom.addPolyline(points, false); // add attribs const props = linestring.properties; for (const name of Object.keys(props)) { polyline.setAttribValue(attribs.get(name), props[name]); } } } /* "geometry": { "type": "Polygon", "coordinates": [ [[35, 10], [45, 45], [15, 40], [10, 20], [35, 10]], [[20, 30], [35, 35], [30, 20], [20, 30]] ] } */ /** * Adds polygons to the model * @param polygons The features to add. * @param model The model */ function add_polygons(polygons: any[], attribs: Map<string, gs.IEntAttrib>, model: gs.IModel, elevation: number): void { const geom: gs.IGeom = model.getGeom(); // create polygons for (const polygon of polygons) { // add geometry, single polygon per feature const points: gs.IPoint[] = geom.addPoints(polygon.geometry.coordinates[0].map((xy) => [xy[0], xy[1], elevation])); const polymesh: gs.IPolymesh = geom.addPolymesh([points]); // add attribs const props = polygon.properties; for (const name of Object.keys(props)) { polymesh.setAttribValue(attribs.get(name), props[name]); } } } /* "geometry": { "type": "MultiLineString", "coordinates": [ [[10, 10], [20, 20], [10, 40]], [[40, 40], [30, 30], [40, 20], [30, 10]] ] } */ /** * Adds multilinestrings to the model * @param multilinestrings The features to add. * @param model The model */ function add_multilinestrings(multilinestrings: any[], attribs: Map<string, gs.IEntAttrib>, model: gs.IModel, elevation: number): void { const geom: gs.IGeom = model.getGeom(); // create polygons for (const multilinestring of multilinestrings) { // add geometry, multiple polyline per feature for (const coordinates of multilinestring.geometry.coordinates) { const points: gs.IPoint[] = geom.addPoints(coordinates.map((xy) => [xy[0], xy[1], elevation])); const polyline: gs.IPolymesh = geom.addPolyline(points, false); // add attribs const props = multilinestring.properties; for (const name of Object.keys(props)) { polyline.setAttribValue(attribs.get(name), props[name]); } } } } /* "geometry": { "type": "MultiPolygon", "coordinates": [ [ [[40, 40], [20, 45], [45, 30], [40, 40]] ], [ [[20, 35], [10, 30], [10, 10], [30, 5], [45, 20], [20, 35]], [[30, 20], [20, 15], [20, 25], [30, 20]] ] ] } */ /** * Adds multipolygons to the model * @param multipolygons The features to add. * @param model The model */ function add_multipolygons(multipolygons: any[], attribs: Map<string, gs.IEntAttrib>, model: gs.IModel, elevation: number): void { const geom: gs.IGeom = model.getGeom(); // create multi polygons for (const multipolygon of multipolygons) { // add geometry, a single mesh per feature const points: gs.IPoint[][] = []; for (const coordinates of multipolygon.geometry.coordinates) { points.push(geom.addPoints(coordinates[0].map((xy) => [xy[0], xy[1], elevation]))); } const polymesh: gs.IPolymesh = geom.addPolymesh(points); // add attribs const props = multipolygon.properties; for (const name of Object.keys(props)) { polymesh.setAttribValue(attribs.get(name), props[name]); } } } // =============================================================================================================== /** * Execute using NPM, models get saved in the /src/assets/ folder. * "npm run geojson" */ if (require.main === module) { console.log("Convert files: geojson..."); // writeGsToJSONFile(geojson(path + "example.geojson"), path + "example.gs"); // writeGsToJSONFile(geojson(path + "example2.geojson"), path + "example2.gs"); // writeGsToJSONFile(geojson(path + "model2_plots.geojson"), path + "model2_plots.gs"); // writeGsToJSONFile(geojson(path + "model2_flat.geojson"), path + "model2_flat.gs"); // writeGsToJSONFile(geojson(path + "All Plots_3414.geojson"), path + "All Plots_3414.gs"); // console.log("Masterplan"); // writeGsToJSONFile(geojson(path + "Masterplan.geojson"), path + "Masterplan.gs"); // console.log("FINAL_RESULT"); // writeGsToJSONFile(geojson(path + "FINAL_RESULT.geojson"), path + "FINAL_RESULT.gs"); console.log("UC1_RESULT"); writeGsToJSONFile(geojson(path + "UC1_RESULT.geojson"), path + "UC1_RESULT.gs"); console.log("Masterplan_FINAL"); writeGsToJSONFile(geojson(path + "Masterplan_FINAL.geojson"), path + "Masterplan_FINAL.gs"); const filenames: string[] = [path + "Masterplan_FINAL.geojson", path + "UC1_RESULT.geojson"]; writeGsToJSONFile(geojsons(filenames), path + "combined.gs"); }