Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions geoscript/geom/linestring.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from com.vividsolutions.jts.geom import Coordinate
from com.vividsolutions.jts.geom import LineString as _LineString
from com.vividsolutions.jts.linearref import LengthIndexedLine
from geoscript import core
from geoscript.geom import Point
import geom

class LineString(_LineString):
Expand All @@ -27,5 +29,56 @@ def __init__(self, *coords):

_LineString.__init__(self, ls.coordinateSequence, geom._factory)

def interpolatePoint(self, position):
"""
Interpolate a :class:`Point <geoscript.geom.Point>` on the :class:`LineString <geoscript.geom.LineString>` at the given position from 0 to 1.

*position* is number between 0 and 1

"""
indexedLine = LengthIndexedLine(self)
length = self.getLength()
coordinate = indexedLine.extractPoint(position * length)
return Point(coordinate.x, coordinate.y)

def locatePoint(self, *coord):
"""
Locate the position of the :class:`point <geoscript.geom.Point>` along this :class:`LineString <geoscript.geom.LineString>`. The position returned is a number between 0 and 1.

*coord* A :class:`Point <geoscript.geom.Point>` or a variable list of x,y,z arguments.

"""
point = coord[0] if isinstance(coord[0], Point) else Point(*coord)
indexedLine = LengthIndexedLine(self)
position = indexedLine.indexOf(point.coordinate)
percentAlong = position / self.getLength()
return percentAlong

def placePoint(self, *coord):
"""
Place or snap the :class:`point <geoscript.geom.Point>` to the `LineString <geoscript.geom.LineString>`. This method returns a new placed `Point <geoscript.geom.Point>`.

*coord* A :class:`Point <geoscript.geom.Point>` or a variable list of x,y,z arguments.

"""
point = coord[0] if isinstance(coord[0], Point) else Point(*coord)
indexedLine = LengthIndexedLine(self)
position = indexedLine.indexOf(point.coordinate)
coord = indexedLine.extractPoint(position)
return Point(coord.x, coord.y)

def subLine(self, start, end):
"""
Extract a sub :class:`LineString <geoscript.geom.LineString>` using a start and end position. Both positions are numbers between 0 and 1. A new :class:`LineString <geoscript.geom.LineString>` is returned.

*start* The start position between 0 and 1

*end* The end position between 0 and 1

"""
indexedLine = LengthIndexedLine(self)
length = self.getLength()
return LineString(indexedLine.extractLine(start * length, end * length))

geom._enhance(LineString)
core.registerTypeMapping(_LineString, LineString)
54 changes: 54 additions & 0 deletions tests/test_geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,57 @@ def testWriteGML(self):

poly = geom.Polygon([[1,2],[3,4],[5,6],[1,2]])
assert str(poly) == str(geom.readGML(geom.writeGML(poly,ver=3.2),ver=3.2))

def testInterpolatePoint(self):
line = geom.LineString(
(1137466.548141059, 650434.9943107369),
(1175272.4129268457, 648011.541439853),
(1185935.6055587344, 632986.1336403737)
)

# start
point1 = line.interpolatePoint(0)
assert str(line.startPoint) == str(point1)

# middle
point2 = line.interpolatePoint(0.5)
assert "POINT (1165562.9204493894 648633.9448037925)" == str(point2)

# end
point3 = line.interpolatePoint(1.0)
assert str(line.endPoint) == str(point3)

def testLocatePoint(self):
line = geom.LineString(
(1137466.548141059, 650434.9943107369),
(1175272.4129268457, 648011.541439853),
(1185935.6055587344, 632986.1336403737)
)
point = geom.Point(1153461.34, 649950.30)
position = line.locatePoint(point)
self.assertAlmostEqual(0.284, position, places=3)
position = line.locatePoint(1153461.34, 649950.30)
self.assertAlmostEqual(0.284, position, places=3)

def testPlacePoint(self):
line = geom.LineString(
(1137466.548141059, 650434.9943107369),
(1175272.4129268457, 648011.541439853),
(1185935.6055587344, 632986.1336403737)
)
point1 = geom.Point(1153461.34, 649950.30)
point2 = line.placePoint(point1)
assert "POINT (1153426.8271476042 649411.899502625)" == str(point2)
point3 = line.placePoint(1153461.34, 649950.30)
assert "POINT (1153426.8271476042 649411.899502625)" == str(point3)

def testSubLine(self):
line = geom.LineString(
(1137466.548141059, 650434.9943107369),
(1175272.4129268457, 648011.541439853),
(1185935.6055587344, 632986.1336403737)
)
subLine = line.subLine(0.33, 0.67)
assert "LINESTRING (1156010.153864557 649246.3016361536, 1175115.6870342216 648021.5879714314)" == str(subLine)