6 votos

Envoltura de GEOS de la funcionalidad en python

He estado buscando sobre cómo obtener GEOSExtractLine disponibles en python.

Miré bien formada origen a si estaba disponible para él, pero no lo es. Estoy tratando de terminar esta funcionalidad en Django, como muchos otros de referenciación lineal métodos (https://code.djangoproject.com/ticket/11948).

He cambiado el código correctamente, pero me estoy poniendo un "GEOSExtractLine" no se encuentra el error al intentar cargar la función. Aquí está la traza:

  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

¿Cómo puedo averiguar el nombre correcto que GEOS publica por este método? Traté de seguir la convención usada por el bien formada y Django del GEOS contenedor, que se encuentran aquí http://geos.osgeo.org/doxygen/classgeos_1_1linearref_1_1LengthIndexedLine.html#a20e3c3e6faa7183e23e3f9a312893aca

Lo que estoy realmente después de que es este:

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])

Algún consejo?

Sean Gillies venir a rescatar? Ayuda! :D

EDIT: de acuerdo con este billete https://code.djangoproject.com/ticket/11948 y los parches se describe he añadido el siguiente código a los archivos correspondientes:

geometry.py (el contenedor):

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 (donde me punto a geos ctype de la biblioteca)

geos_extract_line = geom_output(GEOSFunc('GEOSExtractLine'),[c_double,c_double])

__init__.py

He añadido a la importación de instrucciones para geos_extract_line.

Cuando hago esto, puedo obtener la traza escrito sobre "la función de GEOSEXtractLine no encontrado".

Indagando un poco más en GEOS docs, parece la correcta función de lo que busco se llama Extracto de Línea Por Ubicación (http://geos.osgeo.org/doxygen/classgeos_1_1linearref_1_1ExtractLineByLocation.html)

Última EDICIÓN:

Mi conjetura es que esta función no está publicado por GEOS capi, porque:

>>> 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']

Con esto tengo una visión de todas las funciones publicado por GEOS de la API y no hay ningún Extracto, ExtractLine o extractByIndex, o cualquier cosa.

De hecho, si se mira el CAPI (el publicado API) no es realmente ninguna referencia de estas funciones:

http://trac.osgeo.org/geos/browser/trunk/capi/geos_c.h.in

Aún así, si alguien puede ayudar, se lo agradezco.

Otra edición: PostGIS tiene la funcionalidad. Cómo lo hicieron?

http://postgis.net/docs/ST_Line_Substring.html

Gracias!

7voto

hernan43 Puntos 566

Como de bien formada versión 1.2.14, las coordenadas se slicable. Esto se ve muy similar a GEOSExtractLine, donde un subconjunto de la cadena de línea puede ser extraído.

Aquí están algunos ejemplos de cómo usted puede cortar las coordenadas para extraer una nueva línea de objeto:

from shapely.geometry import LineString, Point

# Original LineString used for examples
line = LineString([(30, 50), (60, 100), (100, 70), (150, 120), (190, 80)])
line.length # 235.58873956203155

# Extract a LineString from first two coordinates
LineString(line.coords[:2]).length # 58.309518948453004
# .. and from the last two coordinates
LineString(line.coords[-2:]).length # 56.568542494923804
# Everything but the first and last coordinate
LineString(line.coords[1:-1]).length # 120.71067811865476
# Every second coordinate
LineString(line.coords[::2]).length # 163.35495027417937
# Reversed/flipped
LineString(line.coords[::-1]).length # 235.58873956203155

etc.

Como para el tema general de obtención de GEOS funcionalidad para bien formada, que es de hecho un @sgillies respuesta. En general, la funcionalidad debe estar apoyado en el SEGURO de C API.


Para extraer una nueva cadena de línea utilizando la referencia lineal métodos, aquí es un complemento de la función en Python puro. Si normalized=True, a continuación, utiliza normalizado start/end de referenciación lineal (es decir, dentro de los [0.0, 1.0]); de lo contrario, el valor predeterminado es de absoluta referencia lineal (es decir, dentro de los [0.0, longitud total]). Negativo end es compatible como el inverso de la distancia desde el final de la cadena de línea.

def extract_line(line, start, end, normalized=False):
    """Extract LineString from `start` to `end`"""
    assert start >= 0, '`start` must be greater than or equal to zero'
    if end < 0:
        if normalized:
            end += 1.0
        else:
            end += line.length
    assert end > start, '`end` must be greater than `start`'
    start_c = line.interpolate(start, normalized).coords[0]
    end_c = line.interpolate(end, normalized).coords[0]
    for start_i, c in enumerate(line.coords):
        if c == start_c:
            start_c = None
            break
        if line.project(Point(c), normalized) >= start:
            break
    for end_i, c in enumerate(line.coords):
        if c == end_c:
            end_c = None
            end_i += 1
            break
        if line.project(Point(c), normalized) >= end:
            break
    extracted = line.coords[start_i:end_i]
    if start_c:
        extracted.insert(0, start_c)
    if end_c:
        extracted.append(end_c)
    return LineString(extracted)

Ejemplos:

# Your example in the question:
extract_line(LineString([(0,0), (10,0)]), 0.5, 1, True).coords[:]
# [(5.0, 0.0), (10.0, 0.0)]

# My example, length of 10.0 removed from each end:
extract_line(line, 10, -10).coords[:]
# [(35.144957554275265, 58.57492925712544), (60.0, 100.0),
#  (100.0, 70.0), (150.0, 120.0), (182.92893218813452, 87.071067811865476)]

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X