landxml 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # landxml
2
2
 
3
+ ## 0.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 4edb0de: Contour elevations from surface min/max elevations and increment are now calculated correctly.
8
+
9
+ ## 0.4.0
10
+
11
+ ### Minor Changes
12
+
13
+ - e2e4513: Rewrote contour lines polyline builder
14
+
3
15
  ## 0.3.0
4
16
 
5
17
  ### Minor Changes
package/dist/index.js CHANGED
@@ -228,61 +228,67 @@ var contourLineOnFace = (face, z) => {
228
228
  return line.length > 0 ? line : void 0;
229
229
  };
230
230
  var linesToPolyLines = (lineSegments) => {
231
+ var _a, _b;
231
232
  if (!Array.isArray(lineSegments) || lineSegments.length === 0) {
232
233
  throw new Error("Invalid input: Please provide a non-empty array of line segments.");
233
234
  }
234
- const segmentsMap = /* @__PURE__ */ new Map();
235
+ const segmentsMapIndexes = {};
235
236
  const polylines = [];
236
- lineSegments.forEach(([start, end]) => {
237
- const startKey = start.join(",");
238
- const endKey = end.join(",");
239
- segmentsMap.set(startKey, segmentsMap.get(startKey) || []);
240
- segmentsMap.set(endKey, segmentsMap.get(endKey) || []);
241
- segmentsMap.get(startKey).push(end);
242
- segmentsMap.get(endKey).push(start);
237
+ const parsedSegmentIndexes = [];
238
+ const lineSegmentStrings = lineSegments.map((v) => v.map((c) => c.join(",")));
239
+ lineSegmentStrings.forEach(([start, end], i) => {
240
+ segmentsMapIndexes[start] = segmentsMapIndexes[start] ? [...segmentsMapIndexes[start] || [], i] : [i];
241
+ segmentsMapIndexes[end] = segmentsMapIndexes[end] ? [...segmentsMapIndexes[end] || [], i] : [i];
243
242
  });
244
- const constructPolyline = (start, polyline) => {
245
- let current = start;
246
- while (segmentsMap.has(current.join(",")) && segmentsMap.get(current.join(",")).length > 0) {
247
- const next = segmentsMap.get(current.join(",")).pop();
248
- polyline.push(current);
249
- if (next) {
250
- const nextKey = next.join(",");
251
- segmentsMap.delete(current.join(","));
252
- current = next;
253
- if (segmentsMap.has(nextKey)) {
254
- segmentsMap.set(
255
- nextKey,
256
- (segmentsMap.get(nextKey) || []).filter((point) => point.join(",") !== current.join(","))
257
- );
258
- }
243
+ for (let i = 0; i < lineSegmentStrings.length; i++) {
244
+ if (parsedSegmentIndexes.includes(i))
245
+ continue;
246
+ parsedSegmentIndexes.push(i);
247
+ let [start, end] = lineSegmentStrings[i];
248
+ let polyline = [start, end];
249
+ while (start && segmentsMapIndexes[start]) {
250
+ const nextLineIndex = (_a = segmentsMapIndexes[start]) == null ? void 0 : _a.find(
251
+ (lineIndex) => !parsedSegmentIndexes.includes(lineIndex)
252
+ );
253
+ if (nextLineIndex) {
254
+ parsedSegmentIndexes.push(nextLineIndex);
255
+ const nextLineSegment = lineSegmentStrings[nextLineIndex];
256
+ const nextLineSegmentPointIndex = nextLineSegment[0] === start ? 1 : 0;
257
+ const newPoint = nextLineSegment[nextLineSegmentPointIndex];
258
+ polyline.unshift(newPoint);
259
+ start = newPoint;
260
+ } else {
261
+ start = null;
259
262
  }
260
263
  }
261
- polyline.push(current);
262
- return polyline;
263
- };
264
- const traverseSegmentsMap = (endpoints, startKey) => {
265
- let start = startKey.split(",").map(Number);
266
- while (endpoints.length > 0) {
267
- const newPolyline = constructPolyline(start, []);
268
- polylines.push(newPolyline);
269
- start = endpoints.pop();
270
- }
271
- };
272
- for (const [startKey, endpoints] of segmentsMap.entries()) {
273
- if (endpoints && endpoints.length === 0) {
274
- continue;
264
+ while (end && segmentsMapIndexes[end]) {
265
+ const nextLineIndex = (_b = segmentsMapIndexes[end]) == null ? void 0 : _b.find(
266
+ (lineIndex) => !parsedSegmentIndexes.includes(lineIndex)
267
+ );
268
+ if (nextLineIndex) {
269
+ parsedSegmentIndexes.push(nextLineIndex);
270
+ const nextLineSegment = lineSegmentStrings[nextLineIndex];
271
+ const nextLineSegmentPointIndex = nextLineSegment[0] === end ? 1 : 0;
272
+ const newPoint = nextLineSegment[nextLineSegmentPointIndex];
273
+ polyline.push(newPoint);
274
+ end = newPoint;
275
+ } else {
276
+ end = null;
277
+ }
275
278
  }
276
- traverseSegmentsMap(endpoints || [], startKey);
279
+ polylines.push(polyline.map((coord) => coord.split(",").map((v) => parseFloat(v))));
277
280
  }
278
281
  return polylines;
279
282
  };
280
- var contourElevations = (minElevation, maxElevation, increment) => {
283
+ var contourElevations = (minElevation, maxElevation, interval) => {
284
+ if (maxElevation >= Infinity) {
285
+ throw new Error("Contour elevations have to be finite numbers");
286
+ }
281
287
  const elevations = [];
282
- const start = Math.ceil(minElevation * 2) / 2;
283
- const end = Math.floor(maxElevation * 2) / 2;
284
- for (let elevation = start; elevation <= end; elevation += increment) {
288
+ let elevation = Math.ceil(minElevation * interval) / interval;
289
+ while (elevation < maxElevation) {
285
290
  elevations.push(elevation);
291
+ elevation += interval;
286
292
  }
287
293
  return elevations;
288
294
  };
package/dist/index.mjs CHANGED
@@ -193,61 +193,67 @@ var contourLineOnFace = (face, z) => {
193
193
  return line.length > 0 ? line : void 0;
194
194
  };
195
195
  var linesToPolyLines = (lineSegments) => {
196
+ var _a, _b;
196
197
  if (!Array.isArray(lineSegments) || lineSegments.length === 0) {
197
198
  throw new Error("Invalid input: Please provide a non-empty array of line segments.");
198
199
  }
199
- const segmentsMap = /* @__PURE__ */ new Map();
200
+ const segmentsMapIndexes = {};
200
201
  const polylines = [];
201
- lineSegments.forEach(([start, end]) => {
202
- const startKey = start.join(",");
203
- const endKey = end.join(",");
204
- segmentsMap.set(startKey, segmentsMap.get(startKey) || []);
205
- segmentsMap.set(endKey, segmentsMap.get(endKey) || []);
206
- segmentsMap.get(startKey).push(end);
207
- segmentsMap.get(endKey).push(start);
202
+ const parsedSegmentIndexes = [];
203
+ const lineSegmentStrings = lineSegments.map((v) => v.map((c) => c.join(",")));
204
+ lineSegmentStrings.forEach(([start, end], i) => {
205
+ segmentsMapIndexes[start] = segmentsMapIndexes[start] ? [...segmentsMapIndexes[start] || [], i] : [i];
206
+ segmentsMapIndexes[end] = segmentsMapIndexes[end] ? [...segmentsMapIndexes[end] || [], i] : [i];
208
207
  });
209
- const constructPolyline = (start, polyline) => {
210
- let current = start;
211
- while (segmentsMap.has(current.join(",")) && segmentsMap.get(current.join(",")).length > 0) {
212
- const next = segmentsMap.get(current.join(",")).pop();
213
- polyline.push(current);
214
- if (next) {
215
- const nextKey = next.join(",");
216
- segmentsMap.delete(current.join(","));
217
- current = next;
218
- if (segmentsMap.has(nextKey)) {
219
- segmentsMap.set(
220
- nextKey,
221
- (segmentsMap.get(nextKey) || []).filter((point) => point.join(",") !== current.join(","))
222
- );
223
- }
208
+ for (let i = 0; i < lineSegmentStrings.length; i++) {
209
+ if (parsedSegmentIndexes.includes(i))
210
+ continue;
211
+ parsedSegmentIndexes.push(i);
212
+ let [start, end] = lineSegmentStrings[i];
213
+ let polyline = [start, end];
214
+ while (start && segmentsMapIndexes[start]) {
215
+ const nextLineIndex = (_a = segmentsMapIndexes[start]) == null ? void 0 : _a.find(
216
+ (lineIndex) => !parsedSegmentIndexes.includes(lineIndex)
217
+ );
218
+ if (nextLineIndex) {
219
+ parsedSegmentIndexes.push(nextLineIndex);
220
+ const nextLineSegment = lineSegmentStrings[nextLineIndex];
221
+ const nextLineSegmentPointIndex = nextLineSegment[0] === start ? 1 : 0;
222
+ const newPoint = nextLineSegment[nextLineSegmentPointIndex];
223
+ polyline.unshift(newPoint);
224
+ start = newPoint;
225
+ } else {
226
+ start = null;
224
227
  }
225
228
  }
226
- polyline.push(current);
227
- return polyline;
228
- };
229
- const traverseSegmentsMap = (endpoints, startKey) => {
230
- let start = startKey.split(",").map(Number);
231
- while (endpoints.length > 0) {
232
- const newPolyline = constructPolyline(start, []);
233
- polylines.push(newPolyline);
234
- start = endpoints.pop();
235
- }
236
- };
237
- for (const [startKey, endpoints] of segmentsMap.entries()) {
238
- if (endpoints && endpoints.length === 0) {
239
- continue;
229
+ while (end && segmentsMapIndexes[end]) {
230
+ const nextLineIndex = (_b = segmentsMapIndexes[end]) == null ? void 0 : _b.find(
231
+ (lineIndex) => !parsedSegmentIndexes.includes(lineIndex)
232
+ );
233
+ if (nextLineIndex) {
234
+ parsedSegmentIndexes.push(nextLineIndex);
235
+ const nextLineSegment = lineSegmentStrings[nextLineIndex];
236
+ const nextLineSegmentPointIndex = nextLineSegment[0] === end ? 1 : 0;
237
+ const newPoint = nextLineSegment[nextLineSegmentPointIndex];
238
+ polyline.push(newPoint);
239
+ end = newPoint;
240
+ } else {
241
+ end = null;
242
+ }
240
243
  }
241
- traverseSegmentsMap(endpoints || [], startKey);
244
+ polylines.push(polyline.map((coord) => coord.split(",").map((v) => parseFloat(v))));
242
245
  }
243
246
  return polylines;
244
247
  };
245
- var contourElevations = (minElevation, maxElevation, increment) => {
248
+ var contourElevations = (minElevation, maxElevation, interval) => {
249
+ if (maxElevation >= Infinity) {
250
+ throw new Error("Contour elevations have to be finite numbers");
251
+ }
246
252
  const elevations = [];
247
- const start = Math.ceil(minElevation * 2) / 2;
248
- const end = Math.floor(maxElevation * 2) / 2;
249
- for (let elevation = start; elevation <= end; elevation += increment) {
253
+ let elevation = Math.ceil(minElevation * interval) / interval;
254
+ while (elevation < maxElevation) {
250
255
  elevations.push(elevation);
256
+ elevation += interval;
251
257
  }
252
258
  return elevations;
253
259
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "landxml",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Parse LandXML surfaces on the modern web.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",