UNPKG

osm-to-svg

Version:

Convert OpenStreetMap (OSM) data to SVG.

162 lines 7.01 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.clipLinesWithinPolygon = clipLinesWithinPolygon; exports.clipPolygonWithinPolygon = clipPolygonWithinPolygon; exports.JSONPropertiesToXMLTags = JSONPropertiesToXMLTags; exports.buildSVG = buildSVG; exports.parseLength = parseLength; exports.getScaleFactor = getScaleFactor; exports.rotateCoordinates = rotateCoordinates; const turf = __importStar(require("@turf/turf")); const xml_escape_1 = __importDefault(require("xml-escape")); const xmlbuilder2_1 = require("xmlbuilder2"); const convert_units_1 = __importDefault(require("convert-units")); function clipLinesWithinPolygon(line, splitter) { const output = []; //Accept what is entirelly within the polygon if (turf.booleanWithin(line, splitter)) output.push(line); //Check if it does intersect the polygon if (turf.booleanIntersects(line, splitter)) { const sliced = turf.lineSplit(line, splitter); if (sliced.features.length) { sliced.features.map((f, i) => f.properties = Object.assign(Object.assign({}, line.properties), { sliced: true, id: `${line.properties.id}/slice/${i}` })); // return only the segments within it output.push(sliced.features.filter(_f => turf.booleanWithin(_f, splitter))); } } return output; } function clipPolygonWithinPolygon(polygon, splitter) { const output = []; //Accept what is entirelly within the polygon if (turf.booleanWithin(polygon, splitter)) output.push(polygon); //Check if it does intersect the polygon if (turf.booleanIntersects(polygon, splitter)) { const sliced = turf.intersect(turf.featureCollection([polygon, splitter])); if (sliced) { sliced.properties = Object.assign(Object.assign({}, polygon.properties), { sliced: true }); output.push(sliced); } } return output; } function JSONPropertiesToXMLTags(obj, separator = '_', prefix = '') { return Object.keys(obj).reduce((acc, key) => { const newKey = `${prefix ? `${prefix}${separator}${key}` : key}`.replace(/:/g, '_'); const value = obj[key]; if (typeof value === 'object' && value !== null) { Object.assign(acc, JSONPropertiesToXMLTags(value, separator, newKey)); } else { acc[newKey] = typeof value === "string" ? (0, xml_escape_1.default)(value) : value; } return acc; }, {}); } // export function buildSVG(props: { width: number | string; height: number | string, svgPaths: string[] }): string { // const doc = create({ version: '1.0' }) // .ele('svg', { // width: typeof props.width === "string" ? props.width : `${props.width}mm`, // height: typeof props.height === "string" ? props.height : `${props.height}mm`, // xmlns: 'http://www.w3.org/2000/svg', // }) // .ele('style') // .txt('path { stroke: black; stroke-width: 0.1; fill: none; }') // .up(); // props.svgPaths.forEach((path) => { // doc.import(create(path).root()); // }); // return doc.end({ prettyPrint: true }); // } function buildSVG(props) { // const offsetX = props.offsetX || 0; // const offsetY = props.offsetY || 0; const doc = (0, xmlbuilder2_1.create)({ version: '1.0' }) .ele('svg', { width: `${props.width}mm`, height: `${props.height}mm`, xmlns: 'http://www.w3.org/2000/svg', viewBox: `0 0 ${props.width}mm ${props.height}mm` }) .ele('style') .txt('path { stroke: black; stroke-width: 0.1; fill: none; }') .up(); // Wrap all paths inside a <g> element with translation const group = doc.ele('g', { // transform: `translate(${props.offsetX} ${(props.offsetY)})` // transform: `rotate(${-(props.bearing||0)}, ${((props.width*(1/3.7795275591))/2)} ${((props.height/(1/3.7795275591))/2)})` }); props.svgPaths.forEach((path) => { group.import((0, xmlbuilder2_1.create)(path).root()); }); return doc.end({ prettyPrint: true }); } function parseLength(value) { if (typeof value === "number") return value; // Default unit is 'mm' if no unit is specified const match = value.toString().match(/^([\d.]+)(mm|cm|m|km|in|ft|yd)?$/); if (!match) throw new Error(`Invalid length format: ${value}`); const [, num, unit = 'mm'] = match; const output = (0, convert_units_1.default)(parseFloat(num)).from(unit).to("mm"); // Convert to mm return output; } function getScaleFactor(scale) { const [a, b] = scale.split(":").map(parseFloat); return b / a; // Converts real-world meters to scaled meters } function rotateCoordinates(x, y, angleInDegrees, pivotX, pivotY) { // Convert angle to radians const angleInRadians = (angleInDegrees * Math.PI) / 180; // Step 1: Translate the point to the origin by subtracting the pivot point const translatedX = x - pivotX; const translatedY = y - pivotY; // Step 2: Apply the rotation formula const rotatedX = translatedX * Math.cos(angleInRadians) + translatedY * Math.sin(angleInRadians); const rotatedY = -translatedX * Math.sin(angleInRadians) + translatedY * Math.cos(angleInRadians); // Step 3: Translate the rotated point back by adding the pivot point const finalX = rotatedX + pivotX; const finalY = rotatedY + pivotY; // Return the final rotated coordinates return [finalX, finalY]; } //# sourceMappingURL=index.js.map