@Test public void invalidPolygonTest() throws Exception { String invalidPolygonWKT = "POLYGON ((737.3223167999995 300.6115043555553, 737.9333944888895 298.8183210666666, 734.6862222222226 300.85357795555547, 731.4519751111111 299.20279893333327, 734.2018474666665 300.0128511999999, 738.8875121777774 297.05722311111094, 739.8749348977781 295.00220529777766, 738.6494663111116 293.04009386666667, 739.8239715555555 293.0595726222223, 740.1680810666667 291.096314311111, 742.0000398222228 290.9779854222222, 742.3454691555562 289.6243484444444, 749.0932650666673 289.5820686222221, 748.3574869333343 288.732512711111, 749.4635434666661 287.48391537777775, 753.4318984533338 287.0207533511109, 752.7391328711119 288.27452984888896, 755.191544604445 287.73796295111106, 755.5325548088895 289.0415468088888, 752.2433166222227 290.37469013333316, 755.0832554666667 290.3079708444443, 757.3606769777789 287.83266702222227, 757.0469688888888 288.9282559999999, 758.1241258666669 288.4486144, 757.7301361777781 289.3541944888889, 759.019374933333 289.7385813333333, 762.2620871111121 286.344590222222, 764.3369841777785 286.08804408888864, 763.6562289777785 291.4026495999999, 761.9839596088887 292.3739113244444, 762.433195235556 293.2922436266665, 764.491995022222 292.8312888888888, 764.9500643555557 293.57284693333327, 763.280534755555 294.41848888888876, 764.0451669333333 293.9469937777776, 764.4738816000008 296.85506275555554, 768.546261333333 302.01597724444446, 775.6844515555549 302.2602808888887, 776.6106026666666 303.69028551111114, 783.5582378666668 304.27941319111096, 783.2538595555561 303.19871999999987, 787.7554090666663 298.98134186666675, 794.2554880000007 299.71247786666663, 797.6559416888895 304.5824398222221, 797.6135708444444 308.9094997333334, 795.8814179555557 311.65627733333326, 792.7038776888885 310.7532003555557, 793.5391431111111 312.6568391111109, 791.1233678222225 313.21184711111096, 790.9637603555566 314.31990613333346, 786.6621866666674 313.7359530666665, 787.1284206933333 317.79396494222215, 790.782462293334 318.9490005333332, 795.4531629511121 317.41458432000013, 798.5147044977784 319.2014870755554, 805.0597802666662 317.9516472888886, 800.2897607111117 324.3483249777778, 804.9756302222222 324.0079928888888, 805.5803818666664 324.53246293333314, 802.7551886222227 326.1091043555555, 805.4876757333341 327.1061617777775, 806.7679487999994 325.7249905777778, 808.28506168889 327.3052273777778, 809.5941888000007 325.7510684444442, 810.282407822222 327.42182684444447, 806.2690104888898 327.7403135999998, 804.4354133333336 330.52595768888864, 806.1467221333342 332.1945315555556, 813.3500842666672 333.1780266666665, 810.6970140444437 333.05601137777785, 809.905211733334 334.4197063111112, 808.371214222223 333.6803783111111, 808.8412529777779 335.16872817777767, 810.1757752888889 335.1138417777777, 806.837216711112 337.65090417777765, 809.8295722666662 338.02354915555566, 806.5739349333335 339.94439111111114, 804.4348672000006 339.03671751111096, 804.6997418666679 340.86749297777783, 803.7017241599997 339.6999008711109, 804.2705720888889 341.68928711111107, 802.6454158222232 342.7817358222221, 802.9273571555559 343.89794133333316, 799.3251982222218 344.9686812444445, 798.3326008888898 348.2100736, 795.3077504000012 350.186894222222, 794.888866133334 352.7691946666664, 796.4690574222222 351.98330880000003, 796.974126080001 352.8888888888889, 743.1952545209415 352.8888888888889, 742.6992861866665 351.8572566755556, 744.536829155556 352.44734008888895, 743.2014876444455 351.15236693333327, 748.4974017422219 346.7928530488887, 739.6970365155557 348.1309798399998, 738.9715939555554 347.24050488888884, 745.8135614577777 343.2114107733332, 746.3448035555557 339.3551587555553, 745.0365866666671 337.3208120888887, 742.4229745777775 336.97228799999993, 742.2775210666668 335.5295857777776, 738.4572728888897 333.7384049777779, 738.0062122666668 330.3192007111111, 736.4435427555554 330.04149191111105, 737.7227235555556 329.5907043555553, 737.7972252444442 327.7324401777778, 735.618653866667 323.65628302222194, 731.5624760888895 323.445248, 729.6628104533329 320.88825173333316, 724.8495416888891 325.83817671111115, 728.683716266667 332.1454705777778, 723.9284423111112 335.5659491555555, 726.6814094222227 337.2705678222221, 732.4142620444445 335.68136533333313, 735.8202225777777 340.1564273777776, 734.3186289777777 344.93486648888893, 730.2431089777783 345.9412992, 729.0137173333333 347.83460693333336, 726.1086065777772 348.7445105777779, 724.168240355556 344.3480007111111, 727.6633571555558 342.8152319999999, 727.2347790222229 340.0118840888888, 722.2705180444445 339.46711608888904, 718.4444444444443 340.97975181660604, 718.4444444444443 309.80668544203286, 720.1516117333331 309.5667256888887, 720.5101027555556 307.5459413333333, 725.4580252444448 305.685447111111, 725.9099050666673 304.59764053333333, 723.7044366222226 305.26751857777776, 724.6772366222231 304.3053681777776, 722.432583111111 303.65232924444445, 725.1405397333338 303.0301013333335, 727.9014257777781 299.77810488888895, 729.228893866667 300.5921621333332, 729.0182684444453 302.0866560000002, 730.9589532444452 302.3723747555555, 729.6039736888888 303.0319308799999, 731.2260579555559 303.69602446222234, 736.3402507377778 302.94866375111087, 737.3223167999995 300.6115043555553))"; Geometry g = wkt.read(invalidPolygonWKT); clipper = new GeometryClipper(new Envelope(-12, 780.0, -12, 396.0)); Geometry result = clipper.clipSafe(g, true, 1); assertTrue(!result.isEmpty()); assertTrue(result.getArea() > 0); }
public Geometry clipSafe(Geometry g, boolean ensureValid, double scale) { try { return clip(g, ensureValid); } catch (TopologyException e) { try { if (((g instanceof Polygon) || (g instanceof MultiPolygon)) && (!g.isValid())) { return clip(g.buffer(0), ensureValid); } } catch (TopologyException e2) { } if (scale != 0) { try { GeometryPrecisionReducer reducer = new GeometryPrecisionReducer(new PrecisionModel(scale)); Geometry reduced = reducer.reduce(g); if (reduced.isEmpty()) { throw new TopologyException("Could not snap geometry to precision model"); } return clip(reduced, ensureValid); } catch (TopologyException e3) { } } if (ensureValid) { try { return clip(g, false); } catch (TopologyException e3) { } } return g; } }
GeometryClipper { public Geometry clipSafe(Geometry g, boolean ensureValid, double scale) { try { return clip(g, ensureValid); } catch (TopologyException e) { try { if (((g instanceof Polygon) || (g instanceof MultiPolygon)) && (!g.isValid())) { return clip(g.buffer(0), ensureValid); } } catch (TopologyException e2) { } if (scale != 0) { try { GeometryPrecisionReducer reducer = new GeometryPrecisionReducer(new PrecisionModel(scale)); Geometry reduced = reducer.reduce(g); if (reduced.isEmpty()) { throw new TopologyException("Could not snap geometry to precision model"); } return clip(reduced, ensureValid); } catch (TopologyException e3) { } } if (ensureValid) { try { return clip(g, false); } catch (TopologyException e3) { } } return g; } } }
GeometryClipper { public Geometry clipSafe(Geometry g, boolean ensureValid, double scale) { try { return clip(g, ensureValid); } catch (TopologyException e) { try { if (((g instanceof Polygon) || (g instanceof MultiPolygon)) && (!g.isValid())) { return clip(g.buffer(0), ensureValid); } } catch (TopologyException e2) { } if (scale != 0) { try { GeometryPrecisionReducer reducer = new GeometryPrecisionReducer(new PrecisionModel(scale)); Geometry reduced = reducer.reduce(g); if (reduced.isEmpty()) { throw new TopologyException("Could not snap geometry to precision model"); } return clip(reduced, ensureValid); } catch (TopologyException e3) { } } if (ensureValid) { try { return clip(g, false); } catch (TopologyException e3) { } } return g; } } GeometryClipper(Envelope bounds); }
GeometryClipper { public Geometry clipSafe(Geometry g, boolean ensureValid, double scale) { try { return clip(g, ensureValid); } catch (TopologyException e) { try { if (((g instanceof Polygon) || (g instanceof MultiPolygon)) && (!g.isValid())) { return clip(g.buffer(0), ensureValid); } } catch (TopologyException e2) { } if (scale != 0) { try { GeometryPrecisionReducer reducer = new GeometryPrecisionReducer(new PrecisionModel(scale)); Geometry reduced = reducer.reduce(g); if (reduced.isEmpty()) { throw new TopologyException("Could not snap geometry to precision model"); } return clip(reduced, ensureValid); } catch (TopologyException e3) { } } if (ensureValid) { try { return clip(g, false); } catch (TopologyException e3) { } } return g; } } GeometryClipper(Envelope bounds); Envelope getBounds(); Geometry clipSafe(Geometry g, boolean ensureValid, double scale); Geometry clip(Geometry g, boolean ensureValid); }
GeometryClipper { public Geometry clipSafe(Geometry g, boolean ensureValid, double scale) { try { return clip(g, ensureValid); } catch (TopologyException e) { try { if (((g instanceof Polygon) || (g instanceof MultiPolygon)) && (!g.isValid())) { return clip(g.buffer(0), ensureValid); } } catch (TopologyException e2) { } if (scale != 0) { try { GeometryPrecisionReducer reducer = new GeometryPrecisionReducer(new PrecisionModel(scale)); Geometry reduced = reducer.reduce(g); if (reduced.isEmpty()) { throw new TopologyException("Could not snap geometry to precision model"); } return clip(reduced, ensureValid); } catch (TopologyException e3) { } } if (ensureValid) { try { return clip(g, false); } catch (TopologyException e3) { } } return g; } } GeometryClipper(Envelope bounds); Envelope getBounds(); Geometry clipSafe(Geometry g, boolean ensureValid, double scale); Geometry clip(Geometry g, boolean ensureValid);  }