Skip to content

Commit

Permalink
Addd TestBuilder metric functions
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-jts committed Mar 4, 2025
1 parent 870db27 commit 7e9a424
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2025 Martin Davis.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jtstest.function;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateSequence;
import org.locationtech.jts.geom.CoordinateSequenceFilter;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jtstest.geomfunction.Metadata;

public class MetricFunctions {

/**
* Returns a line graph of segment lengths.
* Graph is scaled to maximum segment length.
*
* @param geom geometry to sample
* @param numSamples number of points in line graph
* @return line graph of segment lengths
*/
public static Geometry segmentLengths(final Geometry geom,
@Metadata(title="# of samples")
int numSamples) {

if (numSamples < 1)
numSamples = 1;

List<Double> segLen = new ArrayList<Double>();
CoordinateSequenceFilter segLenFilter = new CoordinateSequenceFilter() {

@Override
public void filter(CoordinateSequence seq, int i) {
if (i == 0) {
segLen.add(0.0);
return;
}
Coordinate p0 = seq.getCoordinate(i);
Coordinate p1 = seq.getCoordinate(i-1);
double len = p0.distance(p1);
segLen.add(len);
}

@Override
public boolean isDone() {
return false;
}

@Override
public boolean isGeometryChanged() {
return false;
}

};
geom.apply(segLenFilter);
Collections.sort(segLen);

double maxLen = segLen.get(segLen.size() - 1);
Coordinate[] pts = new Coordinate[numSamples + 1];
int breakSize = segLen.size() / numSamples + 1;
double dx = maxLen / numSamples;
for (int i = 0; i < numSamples + 1; i++) {

double x = (i >= numSamples) ? maxLen : i * dx;

int sampleIndex = i * breakSize;
if (sampleIndex >= segLen.size())
sampleIndex = segLen.size() - 1;
double y = segLen.get(sampleIndex);
pts[i] = new Coordinate(x, y);
}

return geom.getFactory().createLineString(pts);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.locationtech.jtstest.function.LineHandlingFunctions;
import org.locationtech.jtstest.function.LineSegmentFunctions;
import org.locationtech.jtstest.function.LinearReferencingFunctions;
import org.locationtech.jtstest.function.MetricFunctions;
import org.locationtech.jtstest.function.NodingFunctions;
import org.locationtech.jtstest.function.OffsetCurveFunctions;
import org.locationtech.jtstest.function.OrientationFPFunctions;
Expand Down Expand Up @@ -100,6 +101,7 @@ public static GeometryFunctionRegistry createTestBuilderRegistry()
funcRegistry.add(HullFunctions.class);
funcRegistry.add(LinearReferencingFunctions.class);
funcRegistry.add(LineHandlingFunctions.class);
funcRegistry.add(MetricFunctions.class);
funcRegistry.add(NodingFunctions.class);
funcRegistry.add(PolygonizeFunctions.class);
funcRegistry.add(PrecisionFunctions.class);
Expand Down

0 comments on commit 7e9a424

Please sign in to comment.