I've been looking on how to get GEOSExtractLine available in python.
I looked into Shapely source to if it was available for it, but it's not. I'm trying to wrap this funcionality into Django, much like other linear referencing methods (https://code.djangoproject.com/ticket/11948).
I changed the code properly but I'm getting a "GEOSExtractLine" not found error when trying to load the function. Here's the traceback:
File "C:\Python27\lib\site-packages\django\contrib\gis\geos\__init__.py", line 6, in <module>
from django.contrib.gis.geos.geometry import GEOSGeometry, wkt_regex, hex_regex File "C:\Python27\lib\site-packages\django\contrib\gis\geos\geometry.py", line 15, in <module>
from django.contrib.gis.geos.coordseq import GEOSCoordSeq File "C:\Python27\lib\site-packages\django\contrib\gis\geos\coordseq.py", line 10, in <module>
from django.contrib.gis.geos import prototypes as capi File "C:\Python27\lib\site-packages\django\contrib\gis\geos\prototypes\__init__.py", line 13, in <module>
from django.contrib.gis.geos.prototypes.geom import from_hex, from_wkb, from_wkt, \ File "C:\Python27\lib\site-packages\django\contrib\gis\geos\prototypes\geom.py", line 134, in <module>
geos_extract_line = geom_output(GEOSFunc('GEOSExtractLine'),[c_double,c_double]) File "C:\Python27\lib\site-packages\django\contrib\gis\geos\prototypes\threadsafe.py", line 39, in __init__
self.cfunc = getattr(lgeos, func_name) File "C:\Python27\lib\ctypes\__init__.py", line 366, in __getattr__
func = self.__getitem__(name) File "C:\Python27\lib\ctypes\__init__.py", line 371, in __getitem__
func = self._FuncPtr((name_or_ordinal, self)) AttributeError: function 'GEOSExtractLine' not found
How do I find out the correct name that GEOS publishes for this method? I tried to follow the convention used by Shapely and Django's GEOS wrapper, found here http://geos.osgeo.org/doxygen/classgeos_1_1linearref_1_1LengthIndexedLine.html#a20e3c3e6faa7183e23e3f9a312893aca
What I'm truly after is this:
def test_extract_line(self):
line = LineString((0,0),(10,0))
extract = line.extract_line(.5,1)
from_point = Point(5,0)
to_point = Point(10,0)
self.assertEqual(extract[0][0],from_point[0])
self.assertEqual(extract[0][1],from_point[1])
self.assertEqual(extract[1][0],to_point[0])
self.assertEqual(extract[1][1],to_point[1])
Any tips?
Sean Gillies come to rescue? Help! :D
EDIT: based on this ticket https://code.djangoproject.com/ticket/11948 and the patches it describes I've added the following code to the respective files:
geometry.py (the actual wrapper):
def extract_line(self,from_distance,to_distance):
if not isinstance(self,(LineString,MultiLineString)):
raise TypeError('extract line only works on LineString and MultiLineString geometries')
return capi.geos_extract_line(from_distance,to_distance)
geom.py (where I point to geos ctype library)
geos_extract_line = geom_output(GEOSFunc('GEOSExtractLine'),[c_double,c_double])
__init__.py
I've added the import instruction for geos_extract_line.
When I do this, I get the traceback written above "function GEOSEXtractLine not found".
Digging a bit further on GEOS docs, it looks like the correct function I'm after it's called Extract Line By Location (http://geos.osgeo.org/doxygen/classgeos_1_1linearref_1_1ExtractLineByLocation.html)
Lastest EDIT:
My guess is that this function is not published by GEOS capi, because:
>>> from django.contrib.gis.geos import libgeos
>>> libgeos.lgeos
<CDLL 'C:\OSGeo4W\bin\geos_c.dll', handle 4200000 at 2ad9870>
>>> dir(libgeos.lgeos)
['GEOSArea_r', 'GEOSBoundary_r', 'GEOSBuffer_r', 'GEOSContains_r', 'GEOSConvexHull_r', 'GEOSCoordSeq_clone_r', 'GEOSCoordSeq_create_r', 'GEOSCoordSeq_getDimensions_r', 'GEOSCoordSeq_getOrdinate_r', 'GEOSCoordSeq_getSize_r', 'GEOSCoordSeq_getX_r', 'GEOSCoordSeq_getY_r', 'GEOSCoordSeq_getZ_r', 'GEOSCoordSeq_setOrdinate_r', 'GEOSCoordSeq_setX_r', 'GEOSCoordSeq_setY_r', 'GEOSCoordSeq_setZ_r', 'GEOSCrosses_r', 'GEOSDifference_r', 'GEOSDisjoint_r', 'GEOSDistance_r', 'GEOSEnvelope_r', 'GEOSEqualsExact_r', 'GEOSEquals_r', 'GEOSFree_r', 'GEOSGeomFromHEX_buf_r', 'GEOSGeomFromWKB_buf_r', 'GEOSGeomFromWKT_r', 'GEOSGeomToHEX_buf_r', 'GEOSGeomToWKB_buf_r', 'GEOSGeomToWKT_r', 'GEOSGeomTypeId_r', 'GEOSGeomType_r', 'GEOSGeom_clone_r', 'GEOSGeom_createCollection_r', 'GEOSGeom_createLineString_r', 'GEOSGeom_createLinearRing_r', 'GEOSGeom_createPoint_r', 'GEOSGeom_createPolygon_r', 'GEOSGeom_destroy_r', 'GEOSGeom_getCoordSeq_r', 'GEOSGeom_getDimensions_r', 'GEOSGetCentroid_r', 'GEOSGetExteriorRing_r', 'GEOSGetGeometryN_r', 'GEOSGetInteriorRingN_r', 'GEOSGetNumCoordinates_r', 'GEOSGetNumGeometries_r', 'GEOSGetNumInteriorRings_r', 'GEOSGetSRID_r', 'GEOSHasZ_r', 'GEOSInterpolateNormalized_r', 'GEOSInterpolate_r', 'GEOSIntersection_r', 'GEOSIntersects_r', 'GEOSLength_r', 'GEOSLineMerge_r', 'GEOSNormalize_r', 'GEOSOverlaps_r', 'GEOSPointOnSurface_r', 'GEOSPrepare_r', 'GEOSPreparedContainsProperly_r', 'GEOSPreparedContains_r', 'GEOSPreparedCovers_r', 'GEOSPreparedGeom_destroy_r', 'GEOSPreparedIntersects_r', 'GEOSProjectNormalized_r', 'GEOSProject_r', 'GEOSRelatePattern_r', 'GEOSRelate_r', 'GEOSSetSRID_r', 'GEOSSimplify_r', 'GEOSSymDifference_r', 'GEOSTopologyPreserveSimplify_r', 'GEOSTouches_r', 'GEOSUnionCascaded_r', 'GEOSUnion_r', 'GEOSWKBReader_create_r', 'GEOSWKBReader_destroy_r', 'GEOSWKBReader_readHEX_r', 'GEOSWKBReader_read_r', 'GEOSWKBWriter_create_r', 'GEOSWKBWriter_destroy_r', 'GEOSWKBWriter_getByteOrder_r', 'GEOSWKBWriter_getIncludeSRID_r', 'GEOSWKBWriter_getOutputDimension_r', 'GEOSWKBWriter_setByteOrder_r', 'GEOSWKBWriter_setIncludeSRID_r', 'GEOSWKBWriter_setOutputDimension_r', 'GEOSWKBWriter_writeHEX_r', 'GEOSWKBWriter_write_r', 'GEOSWKTReader_create_r', 'GEOSWKTReader_destroy_r', 'GEOSWKTReader_read_r', 'GEOSWKTWriter_create_r', 'GEOSWKTWriter_destroy_r', 'GEOSWKTWriter_write_r', 'GEOSWithin_r', 'GEOSisEmpty_r', 'GEOSisRing_r', 'GEOSisSimple_r', 'GEOSisValidReason_r', 'GEOSisValid_r', 'GEOSversion', '_FuncPtr', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_func_flags_', '_func_restype_', '_handle', '_name', 'finishGEOS_r', 'initGEOS_r']
With this I've got a glimpse of all the functions published by GEOS API and there is no Extract, ExtractLine or extractByIndex, or anything.
In fact, if you look at CAPI (the published API) there is truly no reference of these functions:
http://trac.osgeo.org/geos/browser/trunk/capi/geos_c.h.in
Still, if anyone can help, I appreciate.
Another edit: PostGIS has the funcionality. How did they do it?
http://postgis.net/docs/ST_Line_Substring.html
Thanks!
ExtractLine
is not ingeos_c.h
, which means you can't access these methods from Shapely, or other C API clients (PostGIS, etc.)ST_Line_Substring
does not use GEOS; it uses their own light-weight geometry library, liblwgeom. It is implemented in lwgeom_functions_analytic.c.