internal static Polygon buildPolygon(TDWay outerWay, IList <TDWay> innerWays) { if (innerWays == null || innerWays.Count == 0) { return(buildPolygon(outerWay)); } // outer way geometry LinearRing outerRing = buildLinearRing(outerWay); // inner rings IList <LinearRing> innerRings = new List <LinearRing>(); foreach (TDWay innerWay in innerWays) { // build linear ring LinearRing innerRing = buildLinearRing(innerWay); innerRings.Add(innerRing); } if (innerRings.Count > 0) { // create new polygon LinearRing[] holes = innerRings.ToArray(); return(GEOMETRY_FACTORY.createPolygon(outerRing, holes)); } return(null); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void testClosedAndUnclosedPolygonWithDangling() public virtual void testClosedAndUnclosedPolygonWithDangling() { TDWay[] testWays = new TDWay[] { this.ways[0], this.ways[1], this.ways[2], this.ways[3], this.ways[4] }; this.polygonizer.mergePolygons(testWays); IList <Deque <TDWay> > polygons = this.polygonizer.Polygons; Assert.assertEquals(2, polygons.Count); Deque <TDWay> p1 = polygons[0]; Deque <TDWay> p2 = polygons[1]; if (p1.size() == 3) { Deque <TDWay> temp = p1; p1 = p2; p2 = temp; } Assert.assertEquals(1, p1.size()); Assert.assertEquals(3, p2.size()); Assert.assertTrue(p1.contains(this.ways[0])); Assert.assertTrue(p2.contains(this.ways[1])); Assert.assertTrue(p2.contains(this.ways[2])); Assert.assertTrue(p2.contains(this.ways[3])); Assert.assertEquals(1, this.polygonizer.Dangling.size()); Assert.assertEquals(this.ways[4], this.polygonizer.Dangling.get(0)); Assert.assertTrue(this.polygonizer.Illegal.size() == 0); }
protected internal virtual void countWayTags(TDWay way) { if (way != null) { countWayTags(way.Tags); } }
protected internal virtual void addWayToTiles(TDWay way, int enlargement) { int bboxEnlargementLocal = enlargement; sbyte minZoomLevel = way.MinimumZoomLevel; for (int i = 0; i < this.zoomIntervalConfiguration.NumberOfZoomIntervals; i++) { // is way seen in a zoom interval? if (minZoomLevel <= this.zoomIntervalConfiguration.getMaxZoom(i)) { ISet <TileCoordinate> matchedTiles = GeoUtils.mapWayToTiles(way, this.zoomIntervalConfiguration.getBaseZoom(i), bboxEnlargementLocal); bool added = false; foreach (TileCoordinate matchedTile in matchedTiles) { TileData td = getTileImpl(i, matchedTile.X, matchedTile.Y); if (td != null) { countWayTags(way); this.countWayTileFactor[i]++; added = true; td.addWay(way); } } if (added) { this.countWays[i]++; } } } }
public override void addWay(Way way) { TDWay tdWay = TDWay.fromWay(way, this, this.preferredLanguages); if (tdWay == null) { return; } this.ways.put(tdWay.Id, tdWay); this.maxWayID = Math.Max(this.maxWayID, way.Id); if (tdWay.Coastline) { // find matching tiles on zoom level 12 ISet <TileCoordinate> coastLineTiles = GeoUtils.mapWayToTiles(tdWay, TileInfo.TILE_INFO_ZOOMLEVEL, 0); foreach (TileCoordinate tileCoordinate in coastLineTiles) { TLongHashSet coastlines = this.tilesToCoastlines.get(tileCoordinate); if (coastlines == null) { coastlines = new TLongHashSet(); this.tilesToCoastlines.put(tileCoordinate, coastlines); } coastlines.add(tdWay.Id); } } }
private IList <TDWay> getInnerWaysOfMultipolygon(long[] innerWayIDs) { if (innerWayIDs == null) { return(Collections.emptyList()); } IList <TDWay> res = new List <TDWay>(); foreach (long id in innerWayIDs) { TDWay current = null; try { current = TDWay.fromWay(this.wayIndexReader.get(id), this, this.preferredLanguages); } catch (NoSuchIndexElementException) { current = this.virtualWays.get(id); if (current == null) { LOGGER.fine("multipolygon with outer way id " + id + " references non-existing inner way " + id); continue; } } res.Add(current); } return(res); }
/// <summary> /// Converts a way with potential inner ways to a JTS geometry. /// </summary> /// <param name="way"> /// the way </param> /// <param name="innerWays"> /// the inner ways or null </param> /// <returns> the JTS geometry </returns> public static Geometry toJtsGeometry(TDWay way, IList <TDWay> innerWays) { if (way == null) { LOGGER.warning("way is null"); return(null); } if (way.ForcePolygonLine) { // may build a single line string if inner ways are empty return(buildMultiLineString(way, innerWays)); } if (way.Shape != TDWay.LINE || innerWays != null && innerWays.Count > 0) { // Have to be careful here about polygons and lines again, the problem with // polygons is that a certain direction is forced, so we do not want to reverse // closed lines that are not meant to be polygons // may contain holes if inner ways are not empty Polygon polygon = buildPolygon(way, innerWays); if (polygon.Valid) { return(polygon); } return(repairInvalidPolygon(polygon)); } // not a closed line return(buildLineString(way)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Before public void setUp() public virtual void setUp() { this.polygonizer = new WayPolygonizer(); this.ways = new TDWay[10]; TDNode[] n1 = new TDNode[] { new TDNode(1, 52000000, 13000000, (short)0, (sbyte)0, null, "n1"), new TDNode(2, 52000000, 13000100, (short)0, (sbyte)0, null, "n2"), new TDNode(3, 52000100, 13000100, (short)0, (sbyte)0, null, "n3"), new TDNode(4, 52000100, 13000000, (short)0, (sbyte)0, null, "n4"), new TDNode(1, 52000000, 13000000, (short)0, (sbyte)0, null, "n5") }; TDWay w1 = new TDWay(1, (sbyte)0, "w1", null, null, n1); TDNode[] n2 = new TDNode[] { new TDNode(5, 52000500, 13000500, (short)0, (sbyte)0, null, "n5"), new TDNode(6, 52000500, 13000800, (short)0, (sbyte)0, null, "n6"), new TDNode(7, 52000800, 13000800, (short)0, (sbyte)0, null, "n7") }; TDWay w2 = new TDWay(2, (sbyte)0, "w2", null, null, n2); TDNode[] n3 = new TDNode[] { new TDNode(7, 52000800, 13000800, (short)0, (sbyte)0, null, "n7"), new TDNode(8, 50001000, 13000800, (short)0, (sbyte)0, null, "n8"), new TDNode(9, 52001000, 13001000, (short)0, (sbyte)0, null, "n9"), new TDNode(10, 52001100, 13001000, (short)0, (sbyte)0, null, "n10") }; TDWay w3 = new TDWay(3, (sbyte)0, "w3", null, null, n3); TDNode[] n4 = new TDNode[] { new TDNode(10, 52001100, 13001000, (short)0, (sbyte)0, null, "n11"), new TDNode(11, 50001100, 13000500, (short)0, (sbyte)0, null, "n12"), new TDNode(5, 52000500, 13000500, (short)0, (sbyte)0, null, "n5") }; TDWay w4 = new TDWay(4, (sbyte)0, "w4", null, null, n4); TDNode[] nDangling1 = new TDNode[] { new TDNode(12, 52001000, 13001000, (short)0, (sbyte)0, null, "n12"), new TDNode(13, 50001000, 13001500, (short)0, (sbyte)0, null, "n13"), new TDNode(14, 52001500, 13001500, (short)0, (sbyte)0, null, "n14"), new TDNode(15, 52001600, 13001500, (short)0, (sbyte)0, null, "n15"), new TDNode(16, 52001600, 13001600, (short)0, (sbyte)0, null, "n16") }; TDWay wDangling1 = new TDWay(5, (sbyte)0, "w5", null, null, nDangling1); this.ways[0] = w1; this.ways[1] = w2; this.ways[2] = w3; this.ways[3] = w4; this.ways[4] = wDangling1; }
private RAMTileData fromHDTileData(HDTileData hdt) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final RAMTileData td = new RAMTileData(); RAMTileData td = new RAMTileData(); TLongIterator it = hdt.Pois.GetEnumerator(); while (it.hasNext()) { td.addPOI(TDNode.fromNode(this.nodeIndexReader.get(it.next()), this.preferredLanguages)); } it = hdt.Ways.GetEnumerator(); while (it.hasNext()) { TDWay way = null; long id = it.next(); try { way = TDWay.fromWay(this.wayIndexReader.get(id), this, this.preferredLanguages); td.addWay(way); } catch (NoSuchIndexElementException) { // is it a virtual way? way = this.virtualWays.get(id); if (way != null) { td.addWay(way); } else { LOGGER.finer("referenced way non-existing" + id); } } if (way != null) { if (this.outerToInnerMapping.contains(way.Id)) { way.Shape = TDWay.MULTI_POLYGON; } IList <TDRelation> associatedRelations = this.additionalRelationTags.get(id); if (associatedRelations != null) { foreach (TDRelation tileDataRelation in associatedRelations) { way.mergeRelationInformation(tileDataRelation); } } } } return(td); }
private static bool isClosedPolygon(Deque <TDWay> currentPolygonSegments) { TDWay c1Start = currentPolygonSegments.First; TDWay c1End = currentPolygonSegments.Last; long startFirst = c1Start.ReversedInRelation ? c1Start.WayNodes[c1Start.WayNodes.length - 1].Id : c1Start.WayNodes[0].Id; long endLast = c1End.ReversedInRelation ? c1End.WayNodes[0].Id : c1End.WayNodes[c1End.WayNodes.length - 1].Id; return(startFirst == endLast); }
public override bool execute(long id) { TDWay way = outerInstance.ways.get(id); if (way != null) { res.Add(way); return(true); } return(false); }
protected internal override void handleAdditionalRelationTags(TDWay way, TDRelation relation) { IList <TDRelation> associatedRelations = this.additionalRelationTags.get(way.Id); if (associatedRelations == null) { associatedRelations = new List <>(); this.additionalRelationTags.put(way.Id, associatedRelations); } associatedRelations.Add(relation); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void testSingleUnClosedPolygon() public virtual void testSingleUnClosedPolygon() { TDWay[] testWays = new TDWay[] { this.ways[1], this.ways[2], this.ways[3] }; this.polygonizer.mergePolygons(testWays); IList <Deque <TDWay> > polygons = this.polygonizer.Polygons; Assert.assertEquals(1, polygons.Count); Assert.assertEquals(3, polygons[0].size()); Assert.assertTrue(polygons[0].contains(this.ways[1])); Assert.assertTrue(polygons[0].contains(this.ways[2])); Assert.assertTrue(polygons[0].contains(this.ways[3])); Assert.assertTrue(this.polygonizer.Dangling.size() == 0); Assert.assertTrue(this.polygonizer.Illegal.size() == 0); }
/// <summary> /// Clips a geometry to a tile. /// </summary> /// <param name="way"> /// the way </param> /// <param name="geometry"> /// the geometry </param> /// <param name="tileCoordinate"> /// the tile coordinate </param> /// <param name="enlargementInMeters"> /// the bounding box buffer </param> /// <returns> the clipped geometry </returns> public static Geometry clipToTile(TDWay way, Geometry geometry, TileCoordinate tileCoordinate, int enlargementInMeters) { Geometry tileBBJTS = null; Geometry ret = null; // create tile bounding box tileBBJTS = tileToJTSGeometry(tileCoordinate.X, tileCoordinate.Y, tileCoordinate.Zoomlevel, enlargementInMeters); // clip the geometry by intersection with the bounding box of the tile // may throw a TopologyException try { if (!geometry.Valid) { // this should stop the problem of non-noded intersections that trigger an error when // clipping LOGGER.warning("invalid geometry prior to tile clipping, trying to repair " + way.Id); geometry = JTSUtils.repairInvalidPolygon(geometry); if (!geometry.Valid) { LOGGER.warning("invalid geometry even after attempt to fix " + way.Id); } } ret = tileBBJTS.intersection(geometry); // according to Ludwig (see issue332) valid polygons may become invalid by clipping (at least // in the Python shapely library // we need to investigate this more closely and write approriate test cases // for now, I check whether the resulting polygon is valid and if not try to repair it if ((ret is Polygon || ret is MultiPolygon) && !ret.Valid) { LOGGER.warning("clipped way is not valid, trying to repair it: " + way.Id); ret = JTSUtils.repairInvalidPolygon(ret); if (ret == null) { way.Invalid = true; LOGGER.warning("could not repair invalid polygon: " + way.Id); } } } catch (TopologyException e) { LOGGER.log(Level.WARNING, "JTS cannot clip way, not storing it in data file: " + way.Id, e); way.Invalid = true; return(null); } return(ret); }
// TODO add accounting of average number of tiles per way public override void complete() { this.indexedNodeStore.complete(); this.nodeIndexReader = this.indexedNodeStore.createReader(); this.indexedWayStore.complete(); this.wayIndexReader = this.indexedWayStore.createReader(); // handle relations ReleasableIterator <Relation> relationReader = this.relationStore.iterate(); RelationHandler relationHandler = new RelationHandler(); while (relationReader.hasNext()) { Relation entry = relationReader.next(); TDRelation tdRelation = TDRelation.fromRelation(entry, this, this.preferredLanguages); relationHandler.execute(tdRelation); } // handle ways ReleasableIterator <Way> wayReader = this.wayStore.iterate(); WayHandler wayHandler = new WayHandler(); while (wayReader.hasNext()) { Way way = wayReader.next(); TDWay tdWay = TDWay.fromWay(way, this, this.preferredLanguages); if (tdWay == null) { continue; } IList <TDRelation> associatedRelations = this.additionalRelationTags.get(tdWay.Id); if (associatedRelations != null) { foreach (TDRelation tileDataRelation in associatedRelations) { tdWay.mergeRelationInformation(tileDataRelation); } } wayHandler.execute(tdWay); } OSMTagMapping.Instance.optimizePoiOrdering(this.histogramPoiTags); OSMTagMapping.Instance.optimizeWayOrdering(this.histogramWayTags); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void testSingleClosedPolygon() public virtual void testSingleClosedPolygon() { TDWay[] testWays = new TDWay[] { this.ways[0] }; this.polygonizer.mergePolygons(testWays); IList <Deque <TDWay> > polygons = this.polygonizer.Polygons; Assert.assertEquals(1, polygons.Count); Assert.assertEquals(1, polygons[0].size()); Assert.assertEquals(5, polygons[0].First.WayNodes.length); Assert.assertEquals(1, polygons[0].First.WayNodes[0].Id); Assert.assertEquals(1, polygons[0].First.WayNodes[4].Id); Assert.assertTrue(polygons[0].contains(this.ways[0])); Assert.assertTrue(this.polygonizer.Dangling.size() == 0); Assert.assertTrue(this.polygonizer.Illegal.size() == 0); }
public override TDWay getWay(long id) { if (this.wayIndexReader == null) { throw new System.InvalidOperationException("way store not accessible, call complete() first"); } try { return(TDWay.fromWay(this.wayIndexReader.get(id), this, this.preferredLanguages)); } catch (NoSuchIndexElementException) { LOGGER.finer("way cannot be found in index: " + id); return(null); } }
/// <summary> /// Translates a <seealso cref="TDWay"/> object to an array of JTS <seealso cref="Coordinate"/>. /// </summary> /// <param name="way"> /// the way </param> /// <returns> the array of coordinates </returns> public static Coordinate[] toCoordinates(TDWay way) { Coordinate[] coordinates = new Coordinate[way.WayNodes.length]; if (way.ReversedInRelation) { for (int i = 0; i < coordinates.Length; i++) { coordinates[coordinates.Length - 1 - i] = toCoordinate(way.WayNodes[i]); } } else { for (int i = 0; i < coordinates.Length; i++) { coordinates[i] = toCoordinate(way.WayNodes[i]); } } return(coordinates); }
internal static MultiLineString buildMultiLineString(TDWay outerWay, IList <TDWay> innerWays) { IList <LineString> lineStrings = new List <LineString>(); // outer way geometry lineStrings.Add(buildLineString(outerWay)); // inner strings if (innerWays != null) { foreach (TDWay innerWay in innerWays) { LineString innerRing = buildLineString(innerWay); lineStrings.Add(innerRing); } } return(GEOMETRY_FACTORY.createMultiLineString(lineStrings.ToArray())); }
// **************** WAY OR POI IN TILE ***************** /// <summary> /// Computes which tiles on the given base zoom level need to include the given way (which may be a polygon). /// </summary> /// <param name="way"> /// the way that is mapped to tiles </param> /// <param name="baseZoomLevel"> /// the base zoom level which is used in the mapping </param> /// <param name="enlargementInMeter"> /// amount of pixels that is used to enlarge the bounding box of the way and the tiles in the mapping /// process </param> /// <returns> all tiles on the given base zoom level that need to include the given way, an empty set if no tiles are /// matched </returns> //JAVA TO C# CONVERTER WARNING: 'final' parameters are not available in .NET: //ORIGINAL LINE: public static java.util.Set<org.mapsforge.map.writer.model.TileCoordinate> mapWayToTiles(final org.mapsforge.map.writer.model.TDWay way, final byte baseZoomLevel, final int enlargementInMeter) public static ISet <TileCoordinate> mapWayToTiles(TDWay way, sbyte baseZoomLevel, int enlargementInMeter) { if (way == null) { LOGGER.fine("way is null in mapping to tiles"); return(Collections.emptySet()); } HashSet <TileCoordinate> matchedTiles = new HashSet <TileCoordinate>(); Geometry wayGeometry = JTSUtils.toJTSGeometry(way); if (wayGeometry == null) { way.Invalid = true; LOGGER.fine("unable to create geometry from way: " + way.Id); return(matchedTiles); } TileCoordinate[] bbox = getWayBoundingBox(way, baseZoomLevel, enlargementInMeter); // calculate the tile coordinates and the corresponding bounding boxes try { for (int k = bbox[0].X; k <= bbox[1].X; k++) { for (int l = bbox[0].Y; l <= bbox[1].Y; l++) { Geometry bboxGeometry = tileToJTSGeometry(k, l, baseZoomLevel, enlargementInMeter); if (bboxGeometry.intersects(wayGeometry)) { matchedTiles.Add(new TileCoordinate(k, l, baseZoomLevel)); } } } } catch (TopologyException) { LOGGER.fine("encountered error during mapping of a way to corresponding tiles, way id: " + way.Id); return(Collections.emptySet()); } return(matchedTiles); }
public override ISet <TDWay> getCoastLines(TileCoordinate tc) { if (tc.Zoomlevel <= TileInfo.TILE_INFO_ZOOMLEVEL) { return(Collections.emptySet()); } TileCoordinate correspondingOceanTile = tc.translateToZoomLevel(TileInfo.TILE_INFO_ZOOMLEVEL).get(0); if (this.wayIndexReader == null) { throw new System.InvalidOperationException("way store not accessible, call complete() first"); } TLongHashSet coastlines = this.tilesToCoastlines.get(correspondingOceanTile); if (coastlines == null) { return(Collections.emptySet()); } TLongIterator it = coastlines.GetEnumerator(); HashSet <TDWay> coastlinesAsTDWay = new HashSet <TDWay>(coastlines.size()); while (it.hasNext()) { long id = it.next(); TDWay tdWay = null; try { tdWay = TDWay.fromWay(this.wayIndexReader.get(id), this, this.preferredLanguages); } catch (NoSuchIndexElementException) { LOGGER.finer("coastline way non-existing" + id); } if (tdWay != null) { coastlinesAsTDWay.Add(tdWay); } } return(coastlinesAsTDWay); }
internal static IList <TDWay> wktPolygonToWays(string wktFile) { Geometry geometry = readWKTFile(wktFile); if (geometry == null || !(geometry is Polygon)) { return(null); } Polygon polygon = (Polygon)geometry; IList <TDWay> ret = new List <TDWay>(); TDWay outer = fromLinestring(polygon.ExteriorRing, true); ret.Add(outer); for (int i = 0; i < polygon.NumInteriorRing; i++) { ret.Add(fromLinestring(polygon.getInteriorRingN(i), false)); } return(ret); }
private IList <TDWay> getInnerWaysOfMultipolygon(long[] innerWayIDs) { if (innerWayIDs == null) { return(Collections.emptyList()); } IList <TDWay> res = new List <TDWay>(); foreach (long id in innerWayIDs) { TDWay current = this.ways.get(id); if (current == null) { continue; } res.Add(current); } return(res); }
//JAVA TO C# CONVERTER WARNING: 'final' parameters are not available in .NET: //ORIGINAL LINE: private static org.mapsforge.map.writer.model.TileCoordinate[] getWayBoundingBox(final org.mapsforge.map.writer.model.TDWay way, byte zoomlevel, int enlargementInMeter) private static TileCoordinate[] getWayBoundingBox(TDWay way, sbyte zoomlevel, int enlargementInMeter) { double maxx = double.NegativeInfinity, maxy = double.NegativeInfinity, minx = double.PositiveInfinity, miny = double.PositiveInfinity; foreach (TDNode coordinate in way.WayNodes) { maxy = Math.Max(maxy, LatLongUtils.microdegreesToDegrees(coordinate.Latitude)); miny = Math.Min(miny, LatLongUtils.microdegreesToDegrees(coordinate.Latitude)); maxx = Math.Max(maxx, LatLongUtils.microdegreesToDegrees(coordinate.Longitude)); minx = Math.Min(minx, LatLongUtils.microdegreesToDegrees(coordinate.Longitude)); } double[] epsilonsTopLeft = computeTileEnlargement(maxy, enlargementInMeter); double[] epsilonsBottomRight = computeTileEnlargement(miny, enlargementInMeter); TileCoordinate[] bbox = new TileCoordinate[2]; bbox[0] = new TileCoordinate((int)MercatorProjection.longitudeToTileX(minx - epsilonsTopLeft[1], zoomlevel), (int)MercatorProjection.latitudeToTileY(maxy + epsilonsTopLeft[0], zoomlevel), zoomlevel); bbox[1] = new TileCoordinate((int)MercatorProjection.longitudeToTileX(maxx + epsilonsBottomRight[1], zoomlevel), (int)MercatorProjection.latitudeToTileY(miny - epsilonsBottomRight[0], zoomlevel), zoomlevel); return(bbox); }
/// <summary> /// Simplifies a geometry using the Douglas Peucker algorithm. /// </summary> /// <param name="way"> /// the way </param> /// <param name="geometry"> /// the geometry </param> /// <param name="zoomlevel"> /// the zoom level </param> /// <param name="simplificationFactor"> /// the simplification factor </param> /// <returns> the simplified geometry </returns> public static Geometry simplifyGeometry(TDWay way, Geometry geometry, sbyte zoomlevel, int tileSize, double simplificationFactor) { Geometry ret = null; Envelope bbox = geometry.EnvelopeInternal; // compute maximal absolute latitude (so that we don't need to care if we // are on northern or southern hemisphere) double latMax = Math.Max(Math.Abs(bbox.MaxY), Math.Abs(bbox.MinY)); double deltaLat = deltaLat(simplificationFactor, latMax, zoomlevel, tileSize); try { ret = TopologyPreservingSimplifier.simplify(geometry, deltaLat); } catch (TopologyException e) { LOGGER.log(Level.FINE, "JTS cannot simplify way due to an error, not simplifying way with id: " + way.Id, e); way.Invalid = true; return(geometry); } return(ret); }
private static bool isClosedPolygon(TDWay way) { TDNode[] waynodes = way.WayNodes; return(waynodes[0].Id == waynodes[waynodes.Length - 1].Id); }
public override void addWay(TDWay way) { this.ways.Add(way); }
internal static LineString buildLineString(TDWay way) { Coordinate[] coordinates = JTSUtils.toCoordinates(way); return(GEOMETRY_FACTORY.createLineString(coordinates)); }
/// <summary> /// Internal conversion method to convert our internal data structure for ways to geometry objects in JTS. It will /// care about ways and polygons and will create the right JTS objects. /// </summary> /// <param name="way"> /// TDway which will be converted. Null if we were not able to convert the way to a Geometry object. </param> /// <returns> return Converted way as JTS object. </returns> internal static Geometry toJTSGeometry(TDWay way) { return(toJtsGeometry(way, null)); }
internal static Polygon buildPolygon(TDWay way) { Coordinate[] coordinates = JTSUtils.toCoordinates(way); return(GEOMETRY_FACTORY.createPolygon(GEOMETRY_FACTORY.createLinearRing(coordinates), null)); }