1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2024 Martin Davis
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Public Licence as published
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************/
/**
* Tests the stability of topology-preserving simplification
* (using GEOSTopologyPreserveSimplify).
* The expectation is that repeated calls to GEOSTopologyPreserveSimplify(geom, tol)
* produce identical results.
*
* See https://github.com/libgeos/geos/issues/1107
*/
#include <geos_c.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <deque>
GEOSGeometry* readGeom(std::string& fname) {
std::ifstream f(fname);
std::string line;
if (! std::getline(f, line)) {
return nullptr;
}
auto geom = GEOSGeomFromWKT(line.c_str());
f.close();
return geom;
}
void write(GEOSGeometry* g)
{
GEOSWKTWriter* writer = GEOSWKTWriter_create();
char* wkt = GEOSWKTWriter_write(writer, g);
GEOSWKTWriter_destroy(writer);
std::cout << wkt << std::endl;
GEOSFree(wkt);
}
//---------- Run test ---------------
void run(std::string& fname, int nRuns, double tolerance)
{
initGEOS(nullptr, nullptr);
GEOSGeometry* geom = readGeom(fname);
int nErrors = 0;
for (int i = 0; i < nRuns; i++) {
GEOSGeometry* simp1 = GEOSTopologyPreserveSimplify(geom, tolerance);
GEOSGeometry* simp2 = GEOSTopologyPreserveSimplify(geom, tolerance);
bool isEqualExact = 1 == GEOSEqualsExact(simp1, simp2, 0.0);
GEOSGeometry* diff = GEOSSymDifference(simp1, simp2);
bool isDiffEmpty = 1 == GEOSisEmpty(diff);
//std::cout << "Run " << i << std::endl;
if (! isEqualExact || ! isDiffEmpty) {
nErrors++;
std::cout << "Run " << i << " - simplified results not identical: equals=" << isEqualExact << ", empty=" << isDiffEmpty << std::endl;
write(diff);
}
GEOSGeom_destroy(simp1);
GEOSGeom_destroy(simp2);
GEOSGeom_destroy(diff);
}
std::cout << "Number of tests with non-identical results: " << nErrors << std::endl;
if (nErrors > 0) {
std::cout << "ERRORS FOUND " << std::endl;
}
GEOSGeom_destroy(geom);
}
int main(int argc, char** argv) {
if (argc != 4) {
std::cout << "Reads a geometry from a WKT file" << std::endl;
std::cout << "and executes GEOSTopologyPreserveSimplify(geom, TOL) N times," << std::endl;
std::cout << "checking that the results are identical" << std::endl;
std::cout << std::endl;
std::cout << "Usage: perf_geostpsimplifystable wktfile TOL N" << std::endl;
return 0;
}
std::string fname{argv[1]};
std::cout << "Reading geometry from " << fname << std::endl;
double tolerance = atof(argv[2]);
std::cout << "Tolerance: " << tolerance << std::endl;
int nRuns = std::atoi(argv[3]);
std::cout << "Performing " << nRuns << " tests." << std::endl;
run(fname, nRuns, tolerance);
}
|