Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jorisvandenbossche/2e38c8ae14d273d9d7b117318e23c7ed to your computer and use it in GitHub Desktop.
Save jorisvandenbossche/2e38c8ae14d273d9d7b117318e23c7ed to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {
"editable": true,
"deletable": true
},
"cell_type": "markdown",
"source": "# Experiment of using Cython to speed-up vectorized shapely operations\n"
},
{
"metadata": {
"collapsed": true,
"trusted": true,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "import pandas as pd\nimport geopandas\nimport shapely",
"execution_count": 1,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "For the test example, create an array of Points:"
},
{
"metadata": {
"collapsed": true,
"trusted": true,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "from shapely.geometry import Point",
"execution_count": 2,
"outputs": []
},
{
"metadata": {
"collapsed": false,
"trusted": true,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "a = np.array([Point(i, i) for i in range(10000)], dtype=object)",
"execution_count": 3,
"outputs": []
},
{
"metadata": {
"collapsed": false,
"trusted": true,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "a",
"execution_count": 4,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "array([<shapely.geometry.point.Point object at 0x7f0a43447fd0>,\n <shapely.geometry.point.Point object at 0x7f0a434560b8>,\n <shapely.geometry.point.Point object at 0x7f0a434560f0>, ...,\n <shapely.geometry.point.Point object at 0x7f0a4324cac8>,\n <shapely.geometry.point.Point object at 0x7f0a4324cb00>,\n <shapely.geometry.point.Point object at 0x7f0a4324cb38>], dtype=object)"
},
"metadata": {},
"execution_count": 4
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "and one Polygon:"
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "from shapely.geometry import Polygon",
"execution_count": 4,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "p = Polygon([(10,10), (10,100), (100,100), (100, 10)])",
"execution_count": 5,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "p",
"execution_count": 6,
"outputs": [
{
"output_type": "execute_result",
"data": {
"image/svg+xml": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"6.4 6.4 97.19999999999999 97.19999999999999\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,110.0)\"><path fill-rule=\"evenodd\" fill=\"#66cc99\" stroke=\"#555555\" stroke-width=\"1.9439999999999997\" opacity=\"0.6\" d=\"M 10.0,10.0 L 10.0,100.0 L 100.0,100.0 L 100.0,10.0 L 10.0,10.0 z\" /></g></svg>",
"text/plain": "<shapely.geometry.polygon.Polygon at 0x7f6de8074400>"
},
"metadata": {},
"execution_count": 6
}
]
},
{
"metadata": {
"collapsed": false,
"trusted": true,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "p.__geom__",
"execution_count": 7,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "56971096"
},
"metadata": {},
"execution_count": 7
}
]
},
{
"metadata": {
"collapsed": true,
"trusted": true,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "p._ctypes_data",
"execution_count": 8,
"outputs": []
},
{
"metadata": {
"collapsed": false,
"trusted": true,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "p._geom",
"execution_count": 9,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "56971096"
},
"metadata": {},
"execution_count": 9
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "#### Python function for \"vectorized / element-wise contains\""
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "def contains_py(array, p):\n return np.array([p.contains(p2) for p2 in array])",
"execution_count": 10,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "res1 = contains_py(a, p)\nres1",
"execution_count": 11,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "array([False, False, False, ..., False, False, False], dtype=bool)"
},
"metadata": {},
"execution_count": 11
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "res1.sum()",
"execution_count": 12,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "89"
},
"metadata": {},
"execution_count": 12
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "%timeit contains_py(a, p)",
"execution_count": 13,
"outputs": [
{
"output_type": "stream",
"text": "10 loops, best of 3: 50.7 ms per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "#### Cython function for \"vectorized / element-wise contains\": using cython to do the for loop in C"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "The main performance problem with this vectorized 'contains' function is that the for loop happens in python, making this slow (and this is also how geopandas does it under the hood). \nBut, the actual 'contains' operation happens in C (by calling the GEOS library, wrapped by shapely). So let's try to make use of this fact by doing the for loop in Cython and calling the C GEOS function directly from there, without the overhead of switching to Python."
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "!geos-config --version",
"execution_count": 14,
"outputs": [
{
"output_type": "stream",
"text": "3.6.0\r\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "!geos-config --cflags",
"execution_count": 15,
"outputs": [
{
"output_type": "stream",
"text": "-I/home/joris/miniconda3/include\r\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "!geos-config --clibs",
"execution_count": 16,
"outputs": [
{
"output_type": "stream",
"text": "-L/home/joris/miniconda3/lib -lgeos_c\r\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "(just copy pasted some things together based on https://github.com/Toblerity/Shapely/blob/master/shapely/vectorized/_vectorized.pyx)"
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "%load_ext cython",
"execution_count": 18,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "%%cython -l geos_c -L /home/joris/miniconda3/lib -I /home/joris/miniconda3/include -a\n\nimport cython\ncimport cpython.array\n\nimport numpy as np\ncimport numpy as np\n\nimport shapely.prepared\n\ninclude \"_geos.pxi\"\n\n\n@cython.boundscheck(False)\n@cython.wraparound(False)\ndef contains_cy(array, geometry):\n \n cdef Py_ssize_t idx\n cdef unsigned int n = array.size\n cdef np.ndarray[np.uint8_t, ndim=1, cast=True] result = np.empty(n, dtype=np.uint8)\n\n cdef GEOSContextHandle_t geos_handle\n cdef GEOSPreparedGeometry *geom1\n cdef GEOSGeometry *geom2\n cdef uintptr_t geos_geom\n \n # Prepare the geometry if it hasn't already been prepared.\n if not isinstance(geometry, shapely.prepared.PreparedGeometry):\n geometry = shapely.prepared.prep(geometry)\n \n geos_h = get_geos_context_handle()\n geom1 = geos_from_prepared(geometry)\n \n for idx in xrange(n):\n # Construct a coordinate sequence with our x, y values.\n geos_geom = array[idx]._geom\n geom2 = <GEOSGeometry *>geos_geom\n \n # Put the result of whether the point is \"contained\" by the\n # prepared geometry into the result array. \n result[idx] = <np.uint8_t> GEOSPreparedContains_r(geos_h, geom1, geom2)\n #GEOSGeom_destroy_r(geos_h, geom2)\n\n return result.view(dtype=np.bool)",
"execution_count": 19,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "<IPython.core.display.HTML object>",
"text/html": "<!DOCTYPE html>\n<!-- Generated by Cython 0.24.1 -->\n<html>\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n <title>Cython: _cython_magic_82b59155c5d602a807243f9ffdef2d25.pyx</title>\n <style type=\"text/css\">\n \nbody.cython { font-family: courier; font-size: 12; }\n\n.cython.tag { }\n.cython.line { margin: 0em }\n.cython.code { font-size: 9; color: #444444; display: none; margin: 0px 0px 0px 8px; border-left: 8px none; }\n\n.cython.line .run { background-color: #B0FFB0; }\n.cython.line .mis { background-color: #FFB0B0; }\n.cython.code.run { border-left: 8px solid #B0FFB0; }\n.cython.code.mis { border-left: 8px solid #FFB0B0; }\n\n.cython.code .py_c_api { color: red; }\n.cython.code .py_macro_api { color: #FF7000; }\n.cython.code .pyx_c_api { color: #FF3000; }\n.cython.code .pyx_macro_api { color: #FF7000; }\n.cython.code .refnanny { color: #FFA000; }\n.cython.code .trace { color: #FFA000; }\n.cython.code .error_goto { color: #FFA000; }\n\n.cython.code .coerce { color: #008000; border: 1px dotted #008000 }\n.cython.code .py_attr { color: #FF0000; font-weight: bold; }\n.cython.code .c_attr { color: #0000FF; }\n.cython.code .py_call { color: #FF0000; font-weight: bold; }\n.cython.code .c_call { color: #0000FF; }\n\n.cython.score-0 {background-color: #FFFFff;}\n.cython.score-1 {background-color: #FFFFe7;}\n.cython.score-2 {background-color: #FFFFd4;}\n.cython.score-3 {background-color: #FFFFc4;}\n.cython.score-4 {background-color: #FFFFb6;}\n.cython.score-5 {background-color: #FFFFaa;}\n.cython.score-6 {background-color: #FFFF9f;}\n.cython.score-7 {background-color: #FFFF96;}\n.cython.score-8 {background-color: #FFFF8d;}\n.cython.score-9 {background-color: #FFFF86;}\n.cython.score-10 {background-color: #FFFF7f;}\n.cython.score-11 {background-color: #FFFF79;}\n.cython.score-12 {background-color: #FFFF73;}\n.cython.score-13 {background-color: #FFFF6e;}\n.cython.score-14 {background-color: #FFFF6a;}\n.cython.score-15 {background-color: #FFFF66;}\n.cython.score-16 {background-color: #FFFF62;}\n.cython.score-17 {background-color: #FFFF5e;}\n.cython.score-18 {background-color: #FFFF5b;}\n.cython.score-19 {background-color: #FFFF57;}\n.cython.score-20 {background-color: #FFFF55;}\n.cython.score-21 {background-color: #FFFF52;}\n.cython.score-22 {background-color: #FFFF4f;}\n.cython.score-23 {background-color: #FFFF4d;}\n.cython.score-24 {background-color: #FFFF4b;}\n.cython.score-25 {background-color: #FFFF48;}\n.cython.score-26 {background-color: #FFFF46;}\n.cython.score-27 {background-color: #FFFF44;}\n.cython.score-28 {background-color: #FFFF43;}\n.cython.score-29 {background-color: #FFFF41;}\n.cython.score-30 {background-color: #FFFF3f;}\n.cython.score-31 {background-color: #FFFF3e;}\n.cython.score-32 {background-color: #FFFF3c;}\n.cython.score-33 {background-color: #FFFF3b;}\n.cython.score-34 {background-color: #FFFF39;}\n.cython.score-35 {background-color: #FFFF38;}\n.cython.score-36 {background-color: #FFFF37;}\n.cython.score-37 {background-color: #FFFF36;}\n.cython.score-38 {background-color: #FFFF35;}\n.cython.score-39 {background-color: #FFFF34;}\n.cython.score-40 {background-color: #FFFF33;}\n.cython.score-41 {background-color: #FFFF32;}\n.cython.score-42 {background-color: #FFFF31;}\n.cython.score-43 {background-color: #FFFF30;}\n.cython.score-44 {background-color: #FFFF2f;}\n.cython.score-45 {background-color: #FFFF2e;}\n.cython.score-46 {background-color: #FFFF2d;}\n.cython.score-47 {background-color: #FFFF2c;}\n.cython.score-48 {background-color: #FFFF2b;}\n.cython.score-49 {background-color: #FFFF2b;}\n.cython.score-50 {background-color: #FFFF2a;}\n.cython.score-51 {background-color: #FFFF29;}\n.cython.score-52 {background-color: #FFFF29;}\n.cython.score-53 {background-color: #FFFF28;}\n.cython.score-54 {background-color: #FFFF27;}\n.cython.score-55 {background-color: #FFFF27;}\n.cython.score-56 {background-color: #FFFF26;}\n.cython.score-57 {background-color: #FFFF26;}\n.cython.score-58 {background-color: #FFFF25;}\n.cython.score-59 {background-color: #FFFF24;}\n.cython.score-60 {background-color: #FFFF24;}\n.cython.score-61 {background-color: #FFFF23;}\n.cython.score-62 {background-color: #FFFF23;}\n.cython.score-63 {background-color: #FFFF22;}\n.cython.score-64 {background-color: #FFFF22;}\n.cython.score-65 {background-color: #FFFF22;}\n.cython.score-66 {background-color: #FFFF21;}\n.cython.score-67 {background-color: #FFFF21;}\n.cython.score-68 {background-color: #FFFF20;}\n.cython.score-69 {background-color: #FFFF20;}\n.cython.score-70 {background-color: #FFFF1f;}\n.cython.score-71 {background-color: #FFFF1f;}\n.cython.score-72 {background-color: #FFFF1f;}\n.cython.score-73 {background-color: #FFFF1e;}\n.cython.score-74 {background-color: #FFFF1e;}\n.cython.score-75 {background-color: #FFFF1e;}\n.cython.score-76 {background-color: #FFFF1d;}\n.cython.score-77 {background-color: #FFFF1d;}\n.cython.score-78 {background-color: #FFFF1c;}\n.cython.score-79 {background-color: #FFFF1c;}\n.cython.score-80 {background-color: #FFFF1c;}\n.cython.score-81 {background-color: #FFFF1c;}\n.cython.score-82 {background-color: #FFFF1b;}\n.cython.score-83 {background-color: #FFFF1b;}\n.cython.score-84 {background-color: #FFFF1b;}\n.cython.score-85 {background-color: #FFFF1a;}\n.cython.score-86 {background-color: #FFFF1a;}\n.cython.score-87 {background-color: #FFFF1a;}\n.cython.score-88 {background-color: #FFFF1a;}\n.cython.score-89 {background-color: #FFFF19;}\n.cython.score-90 {background-color: #FFFF19;}\n.cython.score-91 {background-color: #FFFF19;}\n.cython.score-92 {background-color: #FFFF19;}\n.cython.score-93 {background-color: #FFFF18;}\n.cython.score-94 {background-color: #FFFF18;}\n.cython.score-95 {background-color: #FFFF18;}\n.cython.score-96 {background-color: #FFFF18;}\n.cython.score-97 {background-color: #FFFF17;}\n.cython.score-98 {background-color: #FFFF17;}\n.cython.score-99 {background-color: #FFFF17;}\n.cython.score-100 {background-color: #FFFF17;}\n.cython.score-101 {background-color: #FFFF16;}\n.cython.score-102 {background-color: #FFFF16;}\n.cython.score-103 {background-color: #FFFF16;}\n.cython.score-104 {background-color: #FFFF16;}\n.cython.score-105 {background-color: #FFFF16;}\n.cython.score-106 {background-color: #FFFF15;}\n.cython.score-107 {background-color: #FFFF15;}\n.cython.score-108 {background-color: #FFFF15;}\n.cython.score-109 {background-color: #FFFF15;}\n.cython.score-110 {background-color: #FFFF15;}\n.cython.score-111 {background-color: #FFFF15;}\n.cython.score-112 {background-color: #FFFF14;}\n.cython.score-113 {background-color: #FFFF14;}\n.cython.score-114 {background-color: #FFFF14;}\n.cython.score-115 {background-color: #FFFF14;}\n.cython.score-116 {background-color: #FFFF14;}\n.cython.score-117 {background-color: #FFFF14;}\n.cython.score-118 {background-color: #FFFF13;}\n.cython.score-119 {background-color: #FFFF13;}\n.cython.score-120 {background-color: #FFFF13;}\n.cython.score-121 {background-color: #FFFF13;}\n.cython.score-122 {background-color: #FFFF13;}\n.cython.score-123 {background-color: #FFFF13;}\n.cython.score-124 {background-color: #FFFF13;}\n.cython.score-125 {background-color: #FFFF12;}\n.cython.score-126 {background-color: #FFFF12;}\n.cython.score-127 {background-color: #FFFF12;}\n.cython.score-128 {background-color: #FFFF12;}\n.cython.score-129 {background-color: #FFFF12;}\n.cython.score-130 {background-color: #FFFF12;}\n.cython.score-131 {background-color: #FFFF12;}\n.cython.score-132 {background-color: #FFFF11;}\n.cython.score-133 {background-color: #FFFF11;}\n.cython.score-134 {background-color: #FFFF11;}\n.cython.score-135 {background-color: #FFFF11;}\n.cython.score-136 {background-color: #FFFF11;}\n.cython.score-137 {background-color: #FFFF11;}\n.cython.score-138 {background-color: #FFFF11;}\n.cython.score-139 {background-color: #FFFF11;}\n.cython.score-140 {background-color: #FFFF11;}\n.cython.score-141 {background-color: #FFFF10;}\n.cython.score-142 {background-color: #FFFF10;}\n.cython.score-143 {background-color: #FFFF10;}\n.cython.score-144 {background-color: #FFFF10;}\n.cython.score-145 {background-color: #FFFF10;}\n.cython.score-146 {background-color: #FFFF10;}\n.cython.score-147 {background-color: #FFFF10;}\n.cython.score-148 {background-color: #FFFF10;}\n.cython.score-149 {background-color: #FFFF10;}\n.cython.score-150 {background-color: #FFFF0f;}\n.cython.score-151 {background-color: #FFFF0f;}\n.cython.score-152 {background-color: #FFFF0f;}\n.cython.score-153 {background-color: #FFFF0f;}\n.cython.score-154 {background-color: #FFFF0f;}\n.cython.score-155 {background-color: #FFFF0f;}\n.cython.score-156 {background-color: #FFFF0f;}\n.cython.score-157 {background-color: #FFFF0f;}\n.cython.score-158 {background-color: #FFFF0f;}\n.cython.score-159 {background-color: #FFFF0f;}\n.cython.score-160 {background-color: #FFFF0f;}\n.cython.score-161 {background-color: #FFFF0e;}\n.cython.score-162 {background-color: #FFFF0e;}\n.cython.score-163 {background-color: #FFFF0e;}\n.cython.score-164 {background-color: #FFFF0e;}\n.cython.score-165 {background-color: #FFFF0e;}\n.cython.score-166 {background-color: #FFFF0e;}\n.cython.score-167 {background-color: #FFFF0e;}\n.cython.score-168 {background-color: #FFFF0e;}\n.cython.score-169 {background-color: #FFFF0e;}\n.cython.score-170 {background-color: #FFFF0e;}\n.cython.score-171 {background-color: #FFFF0e;}\n.cython.score-172 {background-color: #FFFF0e;}\n.cython.score-173 {background-color: #FFFF0d;}\n.cython.score-174 {background-color: #FFFF0d;}\n.cython.score-175 {background-color: #FFFF0d;}\n.cython.score-176 {background-color: #FFFF0d;}\n.cython.score-177 {background-color: #FFFF0d;}\n.cython.score-178 {background-color: #FFFF0d;}\n.cython.score-179 {background-color: #FFFF0d;}\n.cython.score-180 {background-color: #FFFF0d;}\n.cython.score-181 {background-color: #FFFF0d;}\n.cython.score-182 {background-color: #FFFF0d;}\n.cython.score-183 {background-color: #FFFF0d;}\n.cython.score-184 {background-color: #FFFF0d;}\n.cython.score-185 {background-color: #FFFF0d;}\n.cython.score-186 {background-color: #FFFF0d;}\n.cython.score-187 {background-color: #FFFF0c;}\n.cython.score-188 {background-color: #FFFF0c;}\n.cython.score-189 {background-color: #FFFF0c;}\n.cython.score-190 {background-color: #FFFF0c;}\n.cython.score-191 {background-color: #FFFF0c;}\n.cython.score-192 {background-color: #FFFF0c;}\n.cython.score-193 {background-color: #FFFF0c;}\n.cython.score-194 {background-color: #FFFF0c;}\n.cython.score-195 {background-color: #FFFF0c;}\n.cython.score-196 {background-color: #FFFF0c;}\n.cython.score-197 {background-color: #FFFF0c;}\n.cython.score-198 {background-color: #FFFF0c;}\n.cython.score-199 {background-color: #FFFF0c;}\n.cython.score-200 {background-color: #FFFF0c;}\n.cython.score-201 {background-color: #FFFF0c;}\n.cython.score-202 {background-color: #FFFF0c;}\n.cython.score-203 {background-color: #FFFF0b;}\n.cython.score-204 {background-color: #FFFF0b;}\n.cython.score-205 {background-color: #FFFF0b;}\n.cython.score-206 {background-color: #FFFF0b;}\n.cython.score-207 {background-color: #FFFF0b;}\n.cython.score-208 {background-color: #FFFF0b;}\n.cython.score-209 {background-color: #FFFF0b;}\n.cython.score-210 {background-color: #FFFF0b;}\n.cython.score-211 {background-color: #FFFF0b;}\n.cython.score-212 {background-color: #FFFF0b;}\n.cython.score-213 {background-color: #FFFF0b;}\n.cython.score-214 {background-color: #FFFF0b;}\n.cython.score-215 {background-color: #FFFF0b;}\n.cython.score-216 {background-color: #FFFF0b;}\n.cython.score-217 {background-color: #FFFF0b;}\n.cython.score-218 {background-color: #FFFF0b;}\n.cython.score-219 {background-color: #FFFF0b;}\n.cython.score-220 {background-color: #FFFF0b;}\n.cython.score-221 {background-color: #FFFF0b;}\n.cython.score-222 {background-color: #FFFF0a;}\n.cython.score-223 {background-color: #FFFF0a;}\n.cython.score-224 {background-color: #FFFF0a;}\n.cython.score-225 {background-color: #FFFF0a;}\n.cython.score-226 {background-color: #FFFF0a;}\n.cython.score-227 {background-color: #FFFF0a;}\n.cython.score-228 {background-color: #FFFF0a;}\n.cython.score-229 {background-color: #FFFF0a;}\n.cython.score-230 {background-color: #FFFF0a;}\n.cython.score-231 {background-color: #FFFF0a;}\n.cython.score-232 {background-color: #FFFF0a;}\n.cython.score-233 {background-color: #FFFF0a;}\n.cython.score-234 {background-color: #FFFF0a;}\n.cython.score-235 {background-color: #FFFF0a;}\n.cython.score-236 {background-color: #FFFF0a;}\n.cython.score-237 {background-color: #FFFF0a;}\n.cython.score-238 {background-color: #FFFF0a;}\n.cython.score-239 {background-color: #FFFF0a;}\n.cython.score-240 {background-color: #FFFF0a;}\n.cython.score-241 {background-color: #FFFF0a;}\n.cython.score-242 {background-color: #FFFF0a;}\n.cython.score-243 {background-color: #FFFF0a;}\n.cython.score-244 {background-color: #FFFF0a;}\n.cython.score-245 {background-color: #FFFF0a;}\n.cython.score-246 {background-color: #FFFF09;}\n.cython.score-247 {background-color: #FFFF09;}\n.cython.score-248 {background-color: #FFFF09;}\n.cython.score-249 {background-color: #FFFF09;}\n.cython.score-250 {background-color: #FFFF09;}\n.cython.score-251 {background-color: #FFFF09;}\n.cython.score-252 {background-color: #FFFF09;}\n.cython.score-253 {background-color: #FFFF09;}\n.cython.score-254 {background-color: #FFFF09;}\n.cython .hll { background-color: #ffffcc }\n.cython { background: #f8f8f8; }\n.cython .c { color: #408080; font-style: italic } /* Comment */\n.cython .err { border: 1px solid #FF0000 } /* Error */\n.cython .k { color: #008000; font-weight: bold } /* Keyword */\n.cython .o { color: #666666 } /* Operator */\n.cython .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n.cython .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n.cython .cp { color: #BC7A00 } /* Comment.Preproc */\n.cython .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n.cython .c1 { color: #408080; font-style: italic } /* Comment.Single */\n.cython .cs { color: #408080; font-style: italic } /* Comment.Special */\n.cython .gd { color: #A00000 } /* Generic.Deleted */\n.cython .ge { font-style: italic } /* Generic.Emph */\n.cython .gr { color: #FF0000 } /* Generic.Error */\n.cython .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.cython .gi { color: #00A000 } /* Generic.Inserted */\n.cython .go { color: #888888 } /* Generic.Output */\n.cython .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.cython .gs { font-weight: bold } /* Generic.Strong */\n.cython .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.cython .gt { color: #0044DD } /* Generic.Traceback */\n.cython .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.cython .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.cython .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.cython .kp { color: #008000 } /* Keyword.Pseudo */\n.cython .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.cython .kt { color: #B00040 } /* Keyword.Type */\n.cython .m { color: #666666 } /* Literal.Number */\n.cython .s { color: #BA2121 } /* Literal.String */\n.cython .na { color: #7D9029 } /* Name.Attribute */\n.cython .nb { color: #008000 } /* Name.Builtin */\n.cython .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n.cython .no { color: #880000 } /* Name.Constant */\n.cython .nd { color: #AA22FF } /* Name.Decorator */\n.cython .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.cython .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n.cython .nf { color: #0000FF } /* Name.Function */\n.cython .nl { color: #A0A000 } /* Name.Label */\n.cython .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n.cython .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.cython .nv { color: #19177C } /* Name.Variable */\n.cython .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n.cython .w { color: #bbbbbb } /* Text.Whitespace */\n.cython .mb { color: #666666 } /* Literal.Number.Bin */\n.cython .mf { color: #666666 } /* Literal.Number.Float */\n.cython .mh { color: #666666 } /* Literal.Number.Hex */\n.cython .mi { color: #666666 } /* Literal.Number.Integer */\n.cython .mo { color: #666666 } /* Literal.Number.Oct */\n.cython .sa { color: #BA2121 } /* Literal.String.Affix */\n.cython .sb { color: #BA2121 } /* Literal.String.Backtick */\n.cython .sc { color: #BA2121 } /* Literal.String.Char */\n.cython .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.cython .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.cython .s2 { color: #BA2121 } /* Literal.String.Double */\n.cython .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n.cython .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.cython .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n.cython .sx { color: #008000 } /* Literal.String.Other */\n.cython .sr { color: #BB6688 } /* Literal.String.Regex */\n.cython .s1 { color: #BA2121 } /* Literal.String.Single */\n.cython .ss { color: #19177C } /* Literal.String.Symbol */\n.cython .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.cython .fm { color: #0000FF } /* Name.Function.Magic */\n.cython .vc { color: #19177C } /* Name.Variable.Class */\n.cython .vg { color: #19177C } /* Name.Variable.Global */\n.cython .vi { color: #19177C } /* Name.Variable.Instance */\n.cython .vm { color: #19177C } /* Name.Variable.Magic */\n.cython .il { color: #666666 } /* Literal.Number.Integer.Long */\n </style>\n <script>\n function toggleDiv(id) {\n theDiv = id.nextElementSibling\n if (theDiv.style.display != 'block') theDiv.style.display = 'block';\n else theDiv.style.display = 'none';\n }\n </script>\n</head>\n<body class=\"cython\">\n<p><span style=\"border-bottom: solid 1px grey;\">Generated by Cython 0.24.1</span></p>\n<p>\n <span style=\"background-color: #FFFF00\">Yellow lines</span> hint at Python interaction.<br />\n Click on a line that starts with a \"<code>+</code>\" to see the C code that Cython generated for it.\n</p>\n<div class=\"cython\"><pre class=\"cython line score-0\">&#xA0;<span class=\"\">01</span>: </pre>\n<pre class=\"cython line score-11\" onclick='toggleDiv(this)'>+<span class=\"\">02</span>: <span class=\"k\">import</span> <span class=\"nn\">cython</span></pre>\n<pre class='cython code score-11 '> __pyx_t_1 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_test, __pyx_t_1) &lt; 0) __PYX_ERR(0, 2, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">03</span>: <span class=\"k\">cimport</span> <span class=\"nn\">cpython.array</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">04</span>: </pre>\n<pre class=\"cython line score-8\" onclick='toggleDiv(this)'>+<span class=\"\">05</span>: <span class=\"k\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span></pre>\n<pre class='cython code score-8 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_Import</span>(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_np, __pyx_t_1) &lt; 0) __PYX_ERR(0, 5, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">06</span>: <span class=\"k\">cimport</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">07</span>: </pre>\n<pre class=\"cython line score-8\" onclick='toggleDiv(this)'>+<span class=\"\">08</span>: <span class=\"k\">import</span> <span class=\"nn\">shapely.prepared</span></pre>\n<pre class='cython code score-8 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_Import</span>(__pyx_n_s_shapely_prepared, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_shapely, __pyx_t_1) &lt; 0) __PYX_ERR(0, 8, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">09</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">10</span>: <span class=\"k\">include</span> <span class=\"s\">&quot;_geos.pxi&quot;</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">11</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">12</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">13</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">boundscheck</span><span class=\"p\">(</span><span class=\"bp\">False</span><span class=\"p\">)</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">14</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">wraparound</span><span class=\"p\">(</span><span class=\"bp\">False</span><span class=\"p\">)</span></pre>\n<pre class=\"cython line score-59\" onclick='toggleDiv(this)'>+<span class=\"\">15</span>: <span class=\"k\">def</span> <span class=\"nf\">contains_cy</span><span class=\"p\">(</span><span class=\"n\">array</span><span class=\"p\">,</span> <span class=\"n\">geometry</span><span class=\"p\">):</span></pre>\n<pre class='cython code score-59 '>/* Python wrapper */\nstatic PyObject *__pyx_pw_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_1contains_cy(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\nstatic PyMethodDef __pyx_mdef_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_1contains_cy = {\"contains_cy\", (PyCFunction)__pyx_pw_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_1contains_cy, METH_VARARGS|METH_KEYWORDS, 0};\nstatic PyObject *__pyx_pw_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_1contains_cy(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n PyObject *__pyx_v_array = 0;\n PyObject *__pyx_v_geometry = 0;\n PyObject *__pyx_r = 0;\n <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"contains_cy (wrapper)\", 0);\n {\n static PyObject **__pyx_pyargnames[] = {&amp;__pyx_n_s_array,&amp;__pyx_n_s_geometry,0};\n PyObject* values[2] = {0,0};\n if (unlikely(__pyx_kwds)) {\n Py_ssize_t kw_args;\n const Py_ssize_t pos_args = <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args);\n switch (pos_args) {\n case 2: values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n case 1: values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n case 0: break;\n default: goto __pyx_L5_argtuple_error;\n }\n kw_args = <span class='py_c_api'>PyDict_Size</span>(__pyx_kwds);\n switch (pos_args) {\n case 0:\n if (likely((values[0] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_array)) != 0)) kw_args--;\n else goto __pyx_L5_argtuple_error;\n case 1:\n if (likely((values[1] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_geometry)) != 0)) kw_args--;\n else {\n <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"contains_cy\", 1, 2, 2, 1); __PYX_ERR(0, 15, __pyx_L3_error)\n }\n }\n if (unlikely(kw_args &gt; 0)) {\n if (unlikely(<span class='pyx_c_api'>__Pyx_ParseOptionalKeywords</span>(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"contains_cy\") &lt; 0)) __PYX_ERR(0, 15, __pyx_L3_error)\n }\n } else if (<span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args) != 2) {\n goto __pyx_L5_argtuple_error;\n } else {\n values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n }\n __pyx_v_array = values[0];\n __pyx_v_geometry = values[1];\n }\n goto __pyx_L4_argument_unpacking_done;\n __pyx_L5_argtuple_error:;\n <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"contains_cy\", 1, 2, 2, <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args)); __PYX_ERR(0, 15, __pyx_L3_error)\n __pyx_L3_error:;\n <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_82b59155c5d602a807243f9ffdef2d25.contains_cy\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n return NULL;\n __pyx_L4_argument_unpacking_done:;\n __pyx_r = __pyx_pf_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_contains_cy(__pyx_self, __pyx_v_array, __pyx_v_geometry);\n\n /* function exit code */\n <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n return __pyx_r;\n}\n\nstatic PyObject *__pyx_pf_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_contains_cy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_geometry) {\n Py_ssize_t __pyx_v_idx;\n unsigned int __pyx_v_n;\n PyArrayObject *__pyx_v_result = 0;\n GEOSPreparedGeometry *__pyx_v_geom1;\n GEOSGeometry *__pyx_v_geom2;\n uintptr_t __pyx_v_geos_geom;\n GEOSContextHandle_t __pyx_v_geos_h;\n __Pyx_LocalBuf_ND __pyx_pybuffernd_result;\n __Pyx_Buffer __pyx_pybuffer_result;\n PyObject *__pyx_r = NULL;\n <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"contains_cy\", 0);\n <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_geometry);\n __pyx_pybuffer_result.pybuffer.buf = NULL;\n __pyx_pybuffer_result.refcount = 0;\n __pyx_pybuffernd_result.data = NULL;\n __pyx_pybuffernd_result.rcbuffer = &amp;__pyx_pybuffer_result;\n/* … */\n /* function exit code */\n __pyx_L1_error:;\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_1);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_3);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_5);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_6);\n { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;\n __Pyx_PyThreadState_declare\n __Pyx_PyThreadState_assign\n <span class='pyx_c_api'>__Pyx_ErrFetch</span>(&amp;__pyx_type, &amp;__pyx_value, &amp;__pyx_tb);\n <span class='pyx_c_api'>__Pyx_SafeReleaseBuffer</span>(&amp;__pyx_pybuffernd_result.rcbuffer-&gt;pybuffer);\n <span class='pyx_c_api'>__Pyx_ErrRestore</span>(__pyx_type, __pyx_value, __pyx_tb);}\n <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_82b59155c5d602a807243f9ffdef2d25.contains_cy\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n __pyx_r = NULL;\n goto __pyx_L2;\n __pyx_L0:;\n <span class='pyx_c_api'>__Pyx_SafeReleaseBuffer</span>(&amp;__pyx_pybuffernd_result.rcbuffer-&gt;pybuffer);\n __pyx_L2:;\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>((PyObject *)__pyx_v_result);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_v_geometry);\n <span class='refnanny'>__Pyx_XGIVEREF</span>(__pyx_r);\n <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n return __pyx_r;\n}\n/* … */\n __pyx_tuple__7 = <span class='py_c_api'>PyTuple_Pack</span>(10, __pyx_n_s_array, __pyx_n_s_geometry, __pyx_n_s_idx, __pyx_n_s_n, __pyx_n_s_result, __pyx_n_s_geos_handle, __pyx_n_s_geom1, __pyx_n_s_geom2, __pyx_n_s_geos_geom, __pyx_n_s_geos_h); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 15, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_tuple__7);\n <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_tuple__7);\n/* … */\n __pyx_t_1 = PyCFunction_NewEx(&amp;__pyx_mdef_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_1contains_cy, NULL, __pyx_n_s_cython_magic_82b59155c5d602a807); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_contains_cy, __pyx_t_1) &lt; 0) __PYX_ERR(0, 15, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">16</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">17</span>: <span class=\"k\">cdef</span> <span class=\"kt\">Py_ssize_t</span> <span class=\"nf\">idx</span></pre>\n<pre class=\"cython line score-10\" onclick='toggleDiv(this)'>+<span class=\"\">18</span>: <span class=\"k\">cdef</span> <span class=\"kt\">unsigned</span> <span class=\"kt\">int</span> <span class=\"nf\">n</span> <span class=\"o\">=</span> <span class=\"n\">array</span><span class=\"o\">.</span><span class=\"n\">size</span></pre>\n<pre class='cython code score-10 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_v_array, __pyx_n_s_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 18, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyInt_As_unsigned_int</span>(__pyx_t_1); if (unlikely((__pyx_t_2 == (unsigned int)-1) &amp;&amp; <span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 18, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n __pyx_v_n = __pyx_t_2;\n</pre><pre class=\"cython line score-39\" onclick='toggleDiv(this)'>+<span class=\"\">19</span>: <span class=\"k\">cdef</span> <span class=\"kt\">np</span>.<span class=\"kt\">ndarray</span>[<span class=\"kt\">np</span>.<span class=\"nf\">uint8_t</span><span class=\"p\">,</span> <span class=\"nf\">ndim</span><span class=\"o\">=</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"n\">cast</span><span class=\"o\">=</span><span class=\"bp\">True</span><span class=\"p\">]</span> <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">uint8</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-39 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n __pyx_t_3 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyInt_From_unsigned_int</span>(__pyx_v_n); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n __pyx_t_4 = <span class='py_c_api'>PyTuple_New</span>(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_1);\n <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_4, 0, __pyx_t_1);\n __pyx_t_1 = 0;\n __pyx_t_1 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n __pyx_t_5 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_5, __pyx_n_s_uint8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_5); __pyx_t_5 = 0;\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_6) &lt; 0) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_3, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n if (!(likely(((__pyx_t_6) == Py_None) || likely(<span class='pyx_c_api'>__Pyx_TypeTest</span>(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 19, __pyx_L1_error)\n __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);\n {\n __Pyx_BufFmt_StackElem __pyx_stack[1];\n if (unlikely(<span class='pyx_c_api'>__Pyx_GetBufferAndValidate</span>(&amp;__pyx_pybuffernd_result.rcbuffer-&gt;pybuffer, (PyObject*)__pyx_t_7, &amp;__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 1, __pyx_stack) == -1)) {\n __pyx_v_result = ((PyArrayObject *)Py_None); <span class='pyx_macro_api'>__Pyx_INCREF</span>(Py_None); __pyx_pybuffernd_result.rcbuffer-&gt;pybuffer.buf = NULL;\n __PYX_ERR(0, 19, __pyx_L1_error)\n } else {__pyx_pybuffernd_result.diminfo[0].strides = __pyx_pybuffernd_result.rcbuffer-&gt;pybuffer.strides[0]; __pyx_pybuffernd_result.diminfo[0].shape = __pyx_pybuffernd_result.rcbuffer-&gt;pybuffer.shape[0];\n }\n }\n __pyx_t_7 = 0;\n __pyx_v_result = ((PyArrayObject *)__pyx_t_6);\n __pyx_t_6 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">20</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">21</span>: <span class=\"k\">cdef</span> <span class=\"kt\">GEOSContextHandle_t</span> <span class=\"nf\">geos_handle</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">22</span>: <span class=\"k\">cdef</span> <span class=\"kt\">GEOSPreparedGeometry</span> *<span class=\"nf\">geom1</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">23</span>: <span class=\"k\">cdef</span> <span class=\"kt\">GEOSGeometry</span> *<span class=\"nf\">geom2</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">24</span>: <span class=\"k\">cdef</span> <span class=\"kt\">uintptr_t</span> <span class=\"nf\">geos_geom</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">25</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">26</span>: <span class=\"c\"># Prepare the geometry if it hasn&#39;t already been prepared.</span></pre>\n<pre class=\"cython line score-14\" onclick='toggleDiv(this)'>+<span class=\"\">27</span>: <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">geometry</span><span class=\"p\">,</span> <span class=\"n\">shapely</span><span class=\"o\">.</span><span class=\"n\">prepared</span><span class=\"o\">.</span><span class=\"n\">PreparedGeometry</span><span class=\"p\">):</span></pre>\n<pre class='cython code score-14 '> __pyx_t_6 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_shapely); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 27, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_6, __pyx_n_s_prepared); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 27, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_PreparedGeometry); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 27, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n __pyx_t_8 = <span class='py_c_api'>PyObject_IsInstance</span>(__pyx_v_geometry, __pyx_t_6); if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(0, 27, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n __pyx_t_9 = ((!(__pyx_t_8 != 0)) != 0);\n if (__pyx_t_9) {\n/* … */\n }\n</pre><pre class=\"cython line score-33\" onclick='toggleDiv(this)'>+<span class=\"\">28</span>: <span class=\"n\">geometry</span> <span class=\"o\">=</span> <span class=\"n\">shapely</span><span class=\"o\">.</span><span class=\"n\">prepared</span><span class=\"o\">.</span><span class=\"n\">prep</span><span class=\"p\">(</span><span class=\"n\">geometry</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-33 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_shapely); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_prepared); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_4, __pyx_n_s_prep); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n __pyx_t_4 = NULL;\n if (CYTHON_COMPILING_IN_CPYTHON &amp;&amp; likely(<span class='py_c_api'>PyMethod_Check</span>(__pyx_t_1))) {\n __pyx_t_4 = <span class='py_macro_api'>PyMethod_GET_SELF</span>(__pyx_t_1);\n if (likely(__pyx_t_4)) {\n PyObject* function = <span class='py_macro_api'>PyMethod_GET_FUNCTION</span>(__pyx_t_1);\n <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_INCREF</span>(function);\n <span class='pyx_macro_api'>__Pyx_DECREF_SET</span>(__pyx_t_1, function);\n }\n }\n if (!__pyx_t_4) {\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_CallOneArg</span>(__pyx_t_1, __pyx_v_geometry); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n } else {\n __pyx_t_3 = <span class='py_c_api'>PyTuple_New</span>(1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_4); <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = NULL;\n <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_geometry);\n <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_v_geometry);\n <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_3, 0+1, __pyx_v_geometry);\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n }\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n <span class='pyx_macro_api'>__Pyx_DECREF_SET</span>(__pyx_v_geometry, __pyx_t_6);\n __pyx_t_6 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">29</span>: </pre>\n<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">30</span>: <span class=\"n\">geos_h</span> <span class=\"o\">=</span> <span class=\"n\">get_geos_context_handle</span><span class=\"p\">()</span></pre>\n<pre class='cython code score-0 '> __pyx_v_geos_h = __pyx_f_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_get_geos_context_handle();\n</pre><pre class=\"cython line score-5\" onclick='toggleDiv(this)'>+<span class=\"\">31</span>: <span class=\"n\">geom1</span> <span class=\"o\">=</span> <span class=\"n\">geos_from_prepared</span><span class=\"p\">(</span><span class=\"n\">geometry</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-5 '> __pyx_t_10 = __pyx_f_46_cython_magic_82b59155c5d602a807243f9ffdef2d25_geos_from_prepared(__pyx_v_geometry); if (unlikely(<span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 31, __pyx_L1_error)\n __pyx_v_geom1 = __pyx_t_10;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">32</span>: </pre>\n<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">33</span>: <span class=\"k\">for</span> <span class=\"n\">idx</span> <span class=\"ow\">in</span> <span class=\"nb\">xrange</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">):</span></pre>\n<pre class='cython code score-0 '> __pyx_t_2 = __pyx_v_n;\n for (__pyx_t_11 = 0; __pyx_t_11 &lt; __pyx_t_2; __pyx_t_11+=1) {\n __pyx_v_idx = __pyx_t_11;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">34</span>: <span class=\"c\"># Construct a coordinate sequence with our x, y values.</span></pre>\n<pre class=\"cython line score-13\" onclick='toggleDiv(this)'>+<span class=\"\">35</span>: <span class=\"n\">geos_geom</span> <span class=\"o\">=</span> <span class=\"n\">array</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">_geom</span></pre>\n<pre class='cython code score-13 '> __pyx_t_6 = <span class='pyx_c_api'>__Pyx_GetItemInt</span>(__pyx_v_array, __pyx_v_idx, Py_ssize_t, 1, PyInt_FromSsize_t, 0, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 35, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_6, __pyx_n_s_geom); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n __pyx_t_12 = <span class='pyx_c_api'>__Pyx_PyInt_As_size_t</span>(__pyx_t_1); if (unlikely((__pyx_t_12 == (uintptr_t)-1) &amp;&amp; <span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 35, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n __pyx_v_geos_geom = __pyx_t_12;\n</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">36</span>: <span class=\"n\">geom2</span> <span class=\"o\">=</span> <span class=\"o\">&lt;</span><span class=\"n\">GEOSGeometry</span> <span class=\"o\">*&gt;</span><span class=\"n\">geos_geom</span></pre>\n<pre class='cython code score-0 '> __pyx_v_geom2 = ((GEOSGeometry *)__pyx_v_geos_geom);\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">37</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">38</span>: <span class=\"c\"># Put the result of whether the point is &quot;contained&quot; by the</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">39</span>: <span class=\"c\"># prepared geometry into the result array. </span></pre>\n<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">40</span>: <span class=\"n\">result</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"o\">&lt;</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">uint8_t</span><span class=\"o\">&gt;</span> <span class=\"n\">GEOSPreparedContains_r</span><span class=\"p\">(</span><span class=\"n\">geos_h</span><span class=\"p\">,</span> <span class=\"n\">geom1</span><span class=\"p\">,</span> <span class=\"n\">geom2</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-0 '> __pyx_t_13 = __pyx_v_idx;\n *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint8_t *, __pyx_pybuffernd_result.rcbuffer-&gt;pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_result.diminfo[0].strides) = ((__pyx_t_5numpy_uint8_t)GEOSPreparedContains_r(__pyx_v_geos_h, __pyx_v_geom1, __pyx_v_geom2));\n }\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">41</span>: <span class=\"c\">#GEOSGeom_destroy_r(geos_h, geom2)</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">42</span>: </pre>\n<pre class=\"cython line score-23\" onclick='toggleDiv(this)'>+<span class=\"\">43</span>: <span class=\"k\">return</span> <span class=\"n\">result</span><span class=\"o\">.</span><span class=\"n\">view</span><span class=\"p\">(</span><span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">bool</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-23 '> <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_r);\n __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(((PyObject *)__pyx_v_result), __pyx_n_s_view); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 43, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n __pyx_t_6 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 43, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n __pyx_t_3 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 43, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_3);\n __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_3, __pyx_n_s_bool); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 43, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_3); __pyx_t_3 = 0;\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_4) &lt; 0) __PYX_ERR(0, 43, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_1, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 43, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n __pyx_r = __pyx_t_4;\n __pyx_t_4 = 0;\n goto __pyx_L0;\n</pre></div></body></html>"
},
"metadata": {},
"execution_count": 19
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "res2 = contains_cy(a, p)\nres2",
"execution_count": 20,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "array([False, False, False, ..., False, False, False], dtype=bool)"
},
"metadata": {},
"execution_count": 20
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "res2.sum()",
"execution_count": 21,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "89"
},
"metadata": {},
"execution_count": 21
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "np.testing.assert_array_equal(res1, res2)",
"execution_count": 22,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "%timeit contains_cy(a, p)",
"execution_count": 23,
"outputs": [
{
"output_type": "stream",
"text": "100 loops, best of 3: 2.1 ms per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Already much faster !! \n\nFrom about 50 ms to 2 ms -> 25x speed-up"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "#### Passing `_geom` pointers instead of Geometry objects"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "As can be seen in the annotated cython code above, one of the bottlenecks in the for loop part is `geos_geom = array[idx]._geom` (yellow colored line), where I access the geometry python `object` (`a` is an object dtyped array) and get the `_geom` attribute. This has to switch to python to get the attribute, and therefore gives a slowdown. \n\nLet's try to make an array of those integer `_geom` pointers in advance, and pass this to an adapted version of the cython function:"
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "%%cython -l geos_c -L /home/joris/miniconda3/lib -I /home/joris/miniconda3/include -a\n\nimport cython\ncimport cpython.array\n\nimport numpy as np\ncimport numpy as np\n\nimport shapely.prepared\n\ninclude \"_geos.pxi\"\n\n\n@cython.boundscheck(False)\n@cython.wraparound(False)\ndef contains_cy2(np.int64_t[:] array, geometry):\n \n cdef Py_ssize_t idx\n cdef unsigned int n = array.size\n cdef np.ndarray[np.uint8_t, ndim=1, cast=True] result = np.empty(n, dtype=np.uint8)\n\n cdef GEOSContextHandle_t geos_handle\n cdef GEOSPreparedGeometry *geom1\n cdef GEOSGeometry *geom2\n cdef uintptr_t geos_geom\n \n # Prepare the geometry if it hasn't already been prepared.\n if not isinstance(geometry, shapely.prepared.PreparedGeometry):\n geometry = shapely.prepared.prep(geometry)\n \n geos_h = get_geos_context_handle()\n geom1 = geos_from_prepared(geometry)\n \n for idx in xrange(n):\n geos_geom = array[idx]\n geom2 = <GEOSGeometry *>geos_geom\n\n # Put the result of whether the point is \"contained\" by the\n # prepared geometry into the result array. \n result[idx] = <np.uint8_t> GEOSPreparedContains_r(geos_h, geom1, geom2)\n #GEOSGeom_destroy_r(geos_h, geom2)\n\n return result.view(dtype=np.bool)",
"execution_count": 25,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "<IPython.core.display.HTML object>",
"text/html": "<!DOCTYPE html>\n<!-- Generated by Cython 0.24.1 -->\n<html>\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n <title>Cython: _cython_magic_d349877524f4aa438d2abd5176dcf532.pyx</title>\n <style type=\"text/css\">\n \nbody.cython { font-family: courier; font-size: 12; }\n\n.cython.tag { }\n.cython.line { margin: 0em }\n.cython.code { font-size: 9; color: #444444; display: none; margin: 0px 0px 0px 8px; border-left: 8px none; }\n\n.cython.line .run { background-color: #B0FFB0; }\n.cython.line .mis { background-color: #FFB0B0; }\n.cython.code.run { border-left: 8px solid #B0FFB0; }\n.cython.code.mis { border-left: 8px solid #FFB0B0; }\n\n.cython.code .py_c_api { color: red; }\n.cython.code .py_macro_api { color: #FF7000; }\n.cython.code .pyx_c_api { color: #FF3000; }\n.cython.code .pyx_macro_api { color: #FF7000; }\n.cython.code .refnanny { color: #FFA000; }\n.cython.code .trace { color: #FFA000; }\n.cython.code .error_goto { color: #FFA000; }\n\n.cython.code .coerce { color: #008000; border: 1px dotted #008000 }\n.cython.code .py_attr { color: #FF0000; font-weight: bold; }\n.cython.code .c_attr { color: #0000FF; }\n.cython.code .py_call { color: #FF0000; font-weight: bold; }\n.cython.code .c_call { color: #0000FF; }\n\n.cython.score-0 {background-color: #FFFFff;}\n.cython.score-1 {background-color: #FFFFe7;}\n.cython.score-2 {background-color: #FFFFd4;}\n.cython.score-3 {background-color: #FFFFc4;}\n.cython.score-4 {background-color: #FFFFb6;}\n.cython.score-5 {background-color: #FFFFaa;}\n.cython.score-6 {background-color: #FFFF9f;}\n.cython.score-7 {background-color: #FFFF96;}\n.cython.score-8 {background-color: #FFFF8d;}\n.cython.score-9 {background-color: #FFFF86;}\n.cython.score-10 {background-color: #FFFF7f;}\n.cython.score-11 {background-color: #FFFF79;}\n.cython.score-12 {background-color: #FFFF73;}\n.cython.score-13 {background-color: #FFFF6e;}\n.cython.score-14 {background-color: #FFFF6a;}\n.cython.score-15 {background-color: #FFFF66;}\n.cython.score-16 {background-color: #FFFF62;}\n.cython.score-17 {background-color: #FFFF5e;}\n.cython.score-18 {background-color: #FFFF5b;}\n.cython.score-19 {background-color: #FFFF57;}\n.cython.score-20 {background-color: #FFFF55;}\n.cython.score-21 {background-color: #FFFF52;}\n.cython.score-22 {background-color: #FFFF4f;}\n.cython.score-23 {background-color: #FFFF4d;}\n.cython.score-24 {background-color: #FFFF4b;}\n.cython.score-25 {background-color: #FFFF48;}\n.cython.score-26 {background-color: #FFFF46;}\n.cython.score-27 {background-color: #FFFF44;}\n.cython.score-28 {background-color: #FFFF43;}\n.cython.score-29 {background-color: #FFFF41;}\n.cython.score-30 {background-color: #FFFF3f;}\n.cython.score-31 {background-color: #FFFF3e;}\n.cython.score-32 {background-color: #FFFF3c;}\n.cython.score-33 {background-color: #FFFF3b;}\n.cython.score-34 {background-color: #FFFF39;}\n.cython.score-35 {background-color: #FFFF38;}\n.cython.score-36 {background-color: #FFFF37;}\n.cython.score-37 {background-color: #FFFF36;}\n.cython.score-38 {background-color: #FFFF35;}\n.cython.score-39 {background-color: #FFFF34;}\n.cython.score-40 {background-color: #FFFF33;}\n.cython.score-41 {background-color: #FFFF32;}\n.cython.score-42 {background-color: #FFFF31;}\n.cython.score-43 {background-color: #FFFF30;}\n.cython.score-44 {background-color: #FFFF2f;}\n.cython.score-45 {background-color: #FFFF2e;}\n.cython.score-46 {background-color: #FFFF2d;}\n.cython.score-47 {background-color: #FFFF2c;}\n.cython.score-48 {background-color: #FFFF2b;}\n.cython.score-49 {background-color: #FFFF2b;}\n.cython.score-50 {background-color: #FFFF2a;}\n.cython.score-51 {background-color: #FFFF29;}\n.cython.score-52 {background-color: #FFFF29;}\n.cython.score-53 {background-color: #FFFF28;}\n.cython.score-54 {background-color: #FFFF27;}\n.cython.score-55 {background-color: #FFFF27;}\n.cython.score-56 {background-color: #FFFF26;}\n.cython.score-57 {background-color: #FFFF26;}\n.cython.score-58 {background-color: #FFFF25;}\n.cython.score-59 {background-color: #FFFF24;}\n.cython.score-60 {background-color: #FFFF24;}\n.cython.score-61 {background-color: #FFFF23;}\n.cython.score-62 {background-color: #FFFF23;}\n.cython.score-63 {background-color: #FFFF22;}\n.cython.score-64 {background-color: #FFFF22;}\n.cython.score-65 {background-color: #FFFF22;}\n.cython.score-66 {background-color: #FFFF21;}\n.cython.score-67 {background-color: #FFFF21;}\n.cython.score-68 {background-color: #FFFF20;}\n.cython.score-69 {background-color: #FFFF20;}\n.cython.score-70 {background-color: #FFFF1f;}\n.cython.score-71 {background-color: #FFFF1f;}\n.cython.score-72 {background-color: #FFFF1f;}\n.cython.score-73 {background-color: #FFFF1e;}\n.cython.score-74 {background-color: #FFFF1e;}\n.cython.score-75 {background-color: #FFFF1e;}\n.cython.score-76 {background-color: #FFFF1d;}\n.cython.score-77 {background-color: #FFFF1d;}\n.cython.score-78 {background-color: #FFFF1c;}\n.cython.score-79 {background-color: #FFFF1c;}\n.cython.score-80 {background-color: #FFFF1c;}\n.cython.score-81 {background-color: #FFFF1c;}\n.cython.score-82 {background-color: #FFFF1b;}\n.cython.score-83 {background-color: #FFFF1b;}\n.cython.score-84 {background-color: #FFFF1b;}\n.cython.score-85 {background-color: #FFFF1a;}\n.cython.score-86 {background-color: #FFFF1a;}\n.cython.score-87 {background-color: #FFFF1a;}\n.cython.score-88 {background-color: #FFFF1a;}\n.cython.score-89 {background-color: #FFFF19;}\n.cython.score-90 {background-color: #FFFF19;}\n.cython.score-91 {background-color: #FFFF19;}\n.cython.score-92 {background-color: #FFFF19;}\n.cython.score-93 {background-color: #FFFF18;}\n.cython.score-94 {background-color: #FFFF18;}\n.cython.score-95 {background-color: #FFFF18;}\n.cython.score-96 {background-color: #FFFF18;}\n.cython.score-97 {background-color: #FFFF17;}\n.cython.score-98 {background-color: #FFFF17;}\n.cython.score-99 {background-color: #FFFF17;}\n.cython.score-100 {background-color: #FFFF17;}\n.cython.score-101 {background-color: #FFFF16;}\n.cython.score-102 {background-color: #FFFF16;}\n.cython.score-103 {background-color: #FFFF16;}\n.cython.score-104 {background-color: #FFFF16;}\n.cython.score-105 {background-color: #FFFF16;}\n.cython.score-106 {background-color: #FFFF15;}\n.cython.score-107 {background-color: #FFFF15;}\n.cython.score-108 {background-color: #FFFF15;}\n.cython.score-109 {background-color: #FFFF15;}\n.cython.score-110 {background-color: #FFFF15;}\n.cython.score-111 {background-color: #FFFF15;}\n.cython.score-112 {background-color: #FFFF14;}\n.cython.score-113 {background-color: #FFFF14;}\n.cython.score-114 {background-color: #FFFF14;}\n.cython.score-115 {background-color: #FFFF14;}\n.cython.score-116 {background-color: #FFFF14;}\n.cython.score-117 {background-color: #FFFF14;}\n.cython.score-118 {background-color: #FFFF13;}\n.cython.score-119 {background-color: #FFFF13;}\n.cython.score-120 {background-color: #FFFF13;}\n.cython.score-121 {background-color: #FFFF13;}\n.cython.score-122 {background-color: #FFFF13;}\n.cython.score-123 {background-color: #FFFF13;}\n.cython.score-124 {background-color: #FFFF13;}\n.cython.score-125 {background-color: #FFFF12;}\n.cython.score-126 {background-color: #FFFF12;}\n.cython.score-127 {background-color: #FFFF12;}\n.cython.score-128 {background-color: #FFFF12;}\n.cython.score-129 {background-color: #FFFF12;}\n.cython.score-130 {background-color: #FFFF12;}\n.cython.score-131 {background-color: #FFFF12;}\n.cython.score-132 {background-color: #FFFF11;}\n.cython.score-133 {background-color: #FFFF11;}\n.cython.score-134 {background-color: #FFFF11;}\n.cython.score-135 {background-color: #FFFF11;}\n.cython.score-136 {background-color: #FFFF11;}\n.cython.score-137 {background-color: #FFFF11;}\n.cython.score-138 {background-color: #FFFF11;}\n.cython.score-139 {background-color: #FFFF11;}\n.cython.score-140 {background-color: #FFFF11;}\n.cython.score-141 {background-color: #FFFF10;}\n.cython.score-142 {background-color: #FFFF10;}\n.cython.score-143 {background-color: #FFFF10;}\n.cython.score-144 {background-color: #FFFF10;}\n.cython.score-145 {background-color: #FFFF10;}\n.cython.score-146 {background-color: #FFFF10;}\n.cython.score-147 {background-color: #FFFF10;}\n.cython.score-148 {background-color: #FFFF10;}\n.cython.score-149 {background-color: #FFFF10;}\n.cython.score-150 {background-color: #FFFF0f;}\n.cython.score-151 {background-color: #FFFF0f;}\n.cython.score-152 {background-color: #FFFF0f;}\n.cython.score-153 {background-color: #FFFF0f;}\n.cython.score-154 {background-color: #FFFF0f;}\n.cython.score-155 {background-color: #FFFF0f;}\n.cython.score-156 {background-color: #FFFF0f;}\n.cython.score-157 {background-color: #FFFF0f;}\n.cython.score-158 {background-color: #FFFF0f;}\n.cython.score-159 {background-color: #FFFF0f;}\n.cython.score-160 {background-color: #FFFF0f;}\n.cython.score-161 {background-color: #FFFF0e;}\n.cython.score-162 {background-color: #FFFF0e;}\n.cython.score-163 {background-color: #FFFF0e;}\n.cython.score-164 {background-color: #FFFF0e;}\n.cython.score-165 {background-color: #FFFF0e;}\n.cython.score-166 {background-color: #FFFF0e;}\n.cython.score-167 {background-color: #FFFF0e;}\n.cython.score-168 {background-color: #FFFF0e;}\n.cython.score-169 {background-color: #FFFF0e;}\n.cython.score-170 {background-color: #FFFF0e;}\n.cython.score-171 {background-color: #FFFF0e;}\n.cython.score-172 {background-color: #FFFF0e;}\n.cython.score-173 {background-color: #FFFF0d;}\n.cython.score-174 {background-color: #FFFF0d;}\n.cython.score-175 {background-color: #FFFF0d;}\n.cython.score-176 {background-color: #FFFF0d;}\n.cython.score-177 {background-color: #FFFF0d;}\n.cython.score-178 {background-color: #FFFF0d;}\n.cython.score-179 {background-color: #FFFF0d;}\n.cython.score-180 {background-color: #FFFF0d;}\n.cython.score-181 {background-color: #FFFF0d;}\n.cython.score-182 {background-color: #FFFF0d;}\n.cython.score-183 {background-color: #FFFF0d;}\n.cython.score-184 {background-color: #FFFF0d;}\n.cython.score-185 {background-color: #FFFF0d;}\n.cython.score-186 {background-color: #FFFF0d;}\n.cython.score-187 {background-color: #FFFF0c;}\n.cython.score-188 {background-color: #FFFF0c;}\n.cython.score-189 {background-color: #FFFF0c;}\n.cython.score-190 {background-color: #FFFF0c;}\n.cython.score-191 {background-color: #FFFF0c;}\n.cython.score-192 {background-color: #FFFF0c;}\n.cython.score-193 {background-color: #FFFF0c;}\n.cython.score-194 {background-color: #FFFF0c;}\n.cython.score-195 {background-color: #FFFF0c;}\n.cython.score-196 {background-color: #FFFF0c;}\n.cython.score-197 {background-color: #FFFF0c;}\n.cython.score-198 {background-color: #FFFF0c;}\n.cython.score-199 {background-color: #FFFF0c;}\n.cython.score-200 {background-color: #FFFF0c;}\n.cython.score-201 {background-color: #FFFF0c;}\n.cython.score-202 {background-color: #FFFF0c;}\n.cython.score-203 {background-color: #FFFF0b;}\n.cython.score-204 {background-color: #FFFF0b;}\n.cython.score-205 {background-color: #FFFF0b;}\n.cython.score-206 {background-color: #FFFF0b;}\n.cython.score-207 {background-color: #FFFF0b;}\n.cython.score-208 {background-color: #FFFF0b;}\n.cython.score-209 {background-color: #FFFF0b;}\n.cython.score-210 {background-color: #FFFF0b;}\n.cython.score-211 {background-color: #FFFF0b;}\n.cython.score-212 {background-color: #FFFF0b;}\n.cython.score-213 {background-color: #FFFF0b;}\n.cython.score-214 {background-color: #FFFF0b;}\n.cython.score-215 {background-color: #FFFF0b;}\n.cython.score-216 {background-color: #FFFF0b;}\n.cython.score-217 {background-color: #FFFF0b;}\n.cython.score-218 {background-color: #FFFF0b;}\n.cython.score-219 {background-color: #FFFF0b;}\n.cython.score-220 {background-color: #FFFF0b;}\n.cython.score-221 {background-color: #FFFF0b;}\n.cython.score-222 {background-color: #FFFF0a;}\n.cython.score-223 {background-color: #FFFF0a;}\n.cython.score-224 {background-color: #FFFF0a;}\n.cython.score-225 {background-color: #FFFF0a;}\n.cython.score-226 {background-color: #FFFF0a;}\n.cython.score-227 {background-color: #FFFF0a;}\n.cython.score-228 {background-color: #FFFF0a;}\n.cython.score-229 {background-color: #FFFF0a;}\n.cython.score-230 {background-color: #FFFF0a;}\n.cython.score-231 {background-color: #FFFF0a;}\n.cython.score-232 {background-color: #FFFF0a;}\n.cython.score-233 {background-color: #FFFF0a;}\n.cython.score-234 {background-color: #FFFF0a;}\n.cython.score-235 {background-color: #FFFF0a;}\n.cython.score-236 {background-color: #FFFF0a;}\n.cython.score-237 {background-color: #FFFF0a;}\n.cython.score-238 {background-color: #FFFF0a;}\n.cython.score-239 {background-color: #FFFF0a;}\n.cython.score-240 {background-color: #FFFF0a;}\n.cython.score-241 {background-color: #FFFF0a;}\n.cython.score-242 {background-color: #FFFF0a;}\n.cython.score-243 {background-color: #FFFF0a;}\n.cython.score-244 {background-color: #FFFF0a;}\n.cython.score-245 {background-color: #FFFF0a;}\n.cython.score-246 {background-color: #FFFF09;}\n.cython.score-247 {background-color: #FFFF09;}\n.cython.score-248 {background-color: #FFFF09;}\n.cython.score-249 {background-color: #FFFF09;}\n.cython.score-250 {background-color: #FFFF09;}\n.cython.score-251 {background-color: #FFFF09;}\n.cython.score-252 {background-color: #FFFF09;}\n.cython.score-253 {background-color: #FFFF09;}\n.cython.score-254 {background-color: #FFFF09;}\n.cython .hll { background-color: #ffffcc }\n.cython { background: #f8f8f8; }\n.cython .c { color: #408080; font-style: italic } /* Comment */\n.cython .err { border: 1px solid #FF0000 } /* Error */\n.cython .k { color: #008000; font-weight: bold } /* Keyword */\n.cython .o { color: #666666 } /* Operator */\n.cython .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n.cython .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n.cython .cp { color: #BC7A00 } /* Comment.Preproc */\n.cython .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n.cython .c1 { color: #408080; font-style: italic } /* Comment.Single */\n.cython .cs { color: #408080; font-style: italic } /* Comment.Special */\n.cython .gd { color: #A00000 } /* Generic.Deleted */\n.cython .ge { font-style: italic } /* Generic.Emph */\n.cython .gr { color: #FF0000 } /* Generic.Error */\n.cython .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.cython .gi { color: #00A000 } /* Generic.Inserted */\n.cython .go { color: #888888 } /* Generic.Output */\n.cython .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.cython .gs { font-weight: bold } /* Generic.Strong */\n.cython .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.cython .gt { color: #0044DD } /* Generic.Traceback */\n.cython .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.cython .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.cython .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.cython .kp { color: #008000 } /* Keyword.Pseudo */\n.cython .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.cython .kt { color: #B00040 } /* Keyword.Type */\n.cython .m { color: #666666 } /* Literal.Number */\n.cython .s { color: #BA2121 } /* Literal.String */\n.cython .na { color: #7D9029 } /* Name.Attribute */\n.cython .nb { color: #008000 } /* Name.Builtin */\n.cython .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n.cython .no { color: #880000 } /* Name.Constant */\n.cython .nd { color: #AA22FF } /* Name.Decorator */\n.cython .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.cython .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n.cython .nf { color: #0000FF } /* Name.Function */\n.cython .nl { color: #A0A000 } /* Name.Label */\n.cython .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n.cython .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.cython .nv { color: #19177C } /* Name.Variable */\n.cython .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n.cython .w { color: #bbbbbb } /* Text.Whitespace */\n.cython .mb { color: #666666 } /* Literal.Number.Bin */\n.cython .mf { color: #666666 } /* Literal.Number.Float */\n.cython .mh { color: #666666 } /* Literal.Number.Hex */\n.cython .mi { color: #666666 } /* Literal.Number.Integer */\n.cython .mo { color: #666666 } /* Literal.Number.Oct */\n.cython .sa { color: #BA2121 } /* Literal.String.Affix */\n.cython .sb { color: #BA2121 } /* Literal.String.Backtick */\n.cython .sc { color: #BA2121 } /* Literal.String.Char */\n.cython .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.cython .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.cython .s2 { color: #BA2121 } /* Literal.String.Double */\n.cython .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n.cython .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.cython .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n.cython .sx { color: #008000 } /* Literal.String.Other */\n.cython .sr { color: #BB6688 } /* Literal.String.Regex */\n.cython .s1 { color: #BA2121 } /* Literal.String.Single */\n.cython .ss { color: #19177C } /* Literal.String.Symbol */\n.cython .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.cython .fm { color: #0000FF } /* Name.Function.Magic */\n.cython .vc { color: #19177C } /* Name.Variable.Class */\n.cython .vg { color: #19177C } /* Name.Variable.Global */\n.cython .vi { color: #19177C } /* Name.Variable.Instance */\n.cython .vm { color: #19177C } /* Name.Variable.Magic */\n.cython .il { color: #666666 } /* Literal.Number.Integer.Long */\n </style>\n <script>\n function toggleDiv(id) {\n theDiv = id.nextElementSibling\n if (theDiv.style.display != 'block') theDiv.style.display = 'block';\n else theDiv.style.display = 'none';\n }\n </script>\n</head>\n<body class=\"cython\">\n<p><span style=\"border-bottom: solid 1px grey;\">Generated by Cython 0.24.1</span></p>\n<p>\n <span style=\"background-color: #FFFF00\">Yellow lines</span> hint at Python interaction.<br />\n Click on a line that starts with a \"<code>+</code>\" to see the C code that Cython generated for it.\n</p>\n<div class=\"cython\"><pre class=\"cython line score-0\">&#xA0;<span class=\"\">01</span>: </pre>\n<pre class=\"cython line score-11\" onclick='toggleDiv(this)'>+<span class=\"\">02</span>: <span class=\"k\">import</span> <span class=\"nn\">cython</span></pre>\n<pre class='cython code score-11 '> __pyx_t_1 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_test, __pyx_t_1) &lt; 0) __PYX_ERR(0, 2, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">03</span>: <span class=\"k\">cimport</span> <span class=\"nn\">cpython.array</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">04</span>: </pre>\n<pre class=\"cython line score-8\" onclick='toggleDiv(this)'>+<span class=\"\">05</span>: <span class=\"k\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span></pre>\n<pre class='cython code score-8 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_Import</span>(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_np, __pyx_t_1) &lt; 0) __PYX_ERR(0, 5, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">06</span>: <span class=\"k\">cimport</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">07</span>: </pre>\n<pre class=\"cython line score-8\" onclick='toggleDiv(this)'>+<span class=\"\">08</span>: <span class=\"k\">import</span> <span class=\"nn\">shapely.prepared</span></pre>\n<pre class='cython code score-8 '> __pyx_t_1 = <span class='pyx_c_api'>__Pyx_Import</span>(__pyx_n_s_shapely_prepared, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_shapely, __pyx_t_1) &lt; 0) __PYX_ERR(0, 8, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">09</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">10</span>: <span class=\"k\">include</span> <span class=\"s\">&quot;_geos.pxi&quot;</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">11</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">12</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">13</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">boundscheck</span><span class=\"p\">(</span><span class=\"bp\">False</span><span class=\"p\">)</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">14</span>: <span class=\"nd\">@cython</span><span class=\"o\">.</span><span class=\"n\">wraparound</span><span class=\"p\">(</span><span class=\"bp\">False</span><span class=\"p\">)</span></pre>\n<pre class=\"cython line score-61\" onclick='toggleDiv(this)'>+<span class=\"\">15</span>: <span class=\"k\">def</span> <span class=\"nf\">contains_cy2</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">int64_t</span><span class=\"p\">[:]</span> <span class=\"n\">array</span><span class=\"p\">,</span> <span class=\"n\">geometry</span><span class=\"p\">):</span></pre>\n<pre class='cython code score-61 '>/* Python wrapper */\nstatic PyObject *__pyx_pw_46_cython_magic_d349877524f4aa438d2abd5176dcf532_1contains_cy2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\nstatic PyMethodDef __pyx_mdef_46_cython_magic_d349877524f4aa438d2abd5176dcf532_1contains_cy2 = {\"contains_cy2\", (PyCFunction)__pyx_pw_46_cython_magic_d349877524f4aa438d2abd5176dcf532_1contains_cy2, METH_VARARGS|METH_KEYWORDS, 0};\nstatic PyObject *__pyx_pw_46_cython_magic_d349877524f4aa438d2abd5176dcf532_1contains_cy2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n __Pyx_memviewslice __pyx_v_array = { 0, 0, { 0 }, { 0 }, { 0 } };\n PyObject *__pyx_v_geometry = 0;\n PyObject *__pyx_r = 0;\n <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"contains_cy2 (wrapper)\", 0);\n {\n static PyObject **__pyx_pyargnames[] = {&amp;__pyx_n_s_array,&amp;__pyx_n_s_geometry,0};\n PyObject* values[2] = {0,0};\n if (unlikely(__pyx_kwds)) {\n Py_ssize_t kw_args;\n const Py_ssize_t pos_args = <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args);\n switch (pos_args) {\n case 2: values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n case 1: values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n case 0: break;\n default: goto __pyx_L5_argtuple_error;\n }\n kw_args = <span class='py_c_api'>PyDict_Size</span>(__pyx_kwds);\n switch (pos_args) {\n case 0:\n if (likely((values[0] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_array)) != 0)) kw_args--;\n else goto __pyx_L5_argtuple_error;\n case 1:\n if (likely((values[1] = <span class='py_c_api'>PyDict_GetItem</span>(__pyx_kwds, __pyx_n_s_geometry)) != 0)) kw_args--;\n else {\n <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"contains_cy2\", 1, 2, 2, 1); __PYX_ERR(0, 15, __pyx_L3_error)\n }\n }\n if (unlikely(kw_args &gt; 0)) {\n if (unlikely(<span class='pyx_c_api'>__Pyx_ParseOptionalKeywords</span>(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"contains_cy2\") &lt; 0)) __PYX_ERR(0, 15, __pyx_L3_error)\n }\n } else if (<span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args) != 2) {\n goto __pyx_L5_argtuple_error;\n } else {\n values[0] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 0);\n values[1] = <span class='py_macro_api'>PyTuple_GET_ITEM</span>(__pyx_args, 1);\n }\n __pyx_v_array = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_array.memview)) __PYX_ERR(0, 15, __pyx_L3_error)\n __pyx_v_geometry = values[1];\n }\n goto __pyx_L4_argument_unpacking_done;\n __pyx_L5_argtuple_error:;\n <span class='pyx_c_api'>__Pyx_RaiseArgtupleInvalid</span>(\"contains_cy2\", 1, 2, 2, <span class='py_macro_api'>PyTuple_GET_SIZE</span>(__pyx_args)); __PYX_ERR(0, 15, __pyx_L3_error)\n __pyx_L3_error:;\n <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_d349877524f4aa438d2abd5176dcf532.contains_cy2\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n return NULL;\n __pyx_L4_argument_unpacking_done:;\n __pyx_r = __pyx_pf_46_cython_magic_d349877524f4aa438d2abd5176dcf532_contains_cy2(__pyx_self, __pyx_v_array, __pyx_v_geometry);\n\n /* function exit code */\n <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n return __pyx_r;\n}\n\nstatic PyObject *__pyx_pf_46_cython_magic_d349877524f4aa438d2abd5176dcf532_contains_cy2(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_array, PyObject *__pyx_v_geometry) {\n Py_ssize_t __pyx_v_idx;\n unsigned int __pyx_v_n;\n PyArrayObject *__pyx_v_result = 0;\n GEOSPreparedGeometry *__pyx_v_geom1;\n GEOSGeometry *__pyx_v_geom2;\n uintptr_t __pyx_v_geos_geom;\n GEOSContextHandle_t __pyx_v_geos_h;\n __Pyx_LocalBuf_ND __pyx_pybuffernd_result;\n __Pyx_Buffer __pyx_pybuffer_result;\n PyObject *__pyx_r = NULL;\n <span class='refnanny'>__Pyx_RefNannyDeclarations</span>\n <span class='refnanny'>__Pyx_RefNannySetupContext</span>(\"contains_cy2\", 0);\n <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_geometry);\n __pyx_pybuffer_result.pybuffer.buf = NULL;\n __pyx_pybuffer_result.refcount = 0;\n __pyx_pybuffernd_result.data = NULL;\n __pyx_pybuffernd_result.rcbuffer = &amp;__pyx_pybuffer_result;\n/* … */\n /* function exit code */\n __pyx_L1_error:;\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_1);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_2);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_5);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_t_6);\n { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;\n __Pyx_PyThreadState_declare\n __Pyx_PyThreadState_assign\n <span class='pyx_c_api'>__Pyx_ErrFetch</span>(&amp;__pyx_type, &amp;__pyx_value, &amp;__pyx_tb);\n <span class='pyx_c_api'>__Pyx_SafeReleaseBuffer</span>(&amp;__pyx_pybuffernd_result.rcbuffer-&gt;pybuffer);\n <span class='pyx_c_api'>__Pyx_ErrRestore</span>(__pyx_type, __pyx_value, __pyx_tb);}\n <span class='pyx_c_api'>__Pyx_AddTraceback</span>(\"_cython_magic_d349877524f4aa438d2abd5176dcf532.contains_cy2\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n __pyx_r = NULL;\n goto __pyx_L2;\n __pyx_L0:;\n <span class='pyx_c_api'>__Pyx_SafeReleaseBuffer</span>(&amp;__pyx_pybuffernd_result.rcbuffer-&gt;pybuffer);\n __pyx_L2:;\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>((PyObject *)__pyx_v_result);\n __PYX_XDEC_MEMVIEW(&amp;__pyx_v_array, 1);\n <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_v_geometry);\n <span class='refnanny'>__Pyx_XGIVEREF</span>(__pyx_r);\n <span class='refnanny'>__Pyx_RefNannyFinishContext</span>();\n return __pyx_r;\n}\n/* … */\n __pyx_tuple__20 = <span class='py_c_api'>PyTuple_Pack</span>(10, __pyx_n_s_array, __pyx_n_s_geometry, __pyx_n_s_idx, __pyx_n_s_n, __pyx_n_s_result, __pyx_n_s_geos_handle, __pyx_n_s_geom1, __pyx_n_s_geom2, __pyx_n_s_geos_geom, __pyx_n_s_geos_h); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(0, 15, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_tuple__20);\n <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_tuple__20);\n/* … */\n __pyx_t_1 = PyCFunction_NewEx(&amp;__pyx_mdef_46_cython_magic_d349877524f4aa438d2abd5176dcf532_1contains_cy2, NULL, __pyx_n_s_cython_magic_d349877524f4aa438d); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_d, __pyx_n_s_contains_cy2, __pyx_t_1) &lt; 0) __PYX_ERR(0, 15, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n __pyx_codeobj__21 = (PyObject*)<span class='pyx_c_api'>__Pyx_PyCode_New</span>(2, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_joris_cache_ipython_cython, __pyx_n_s_contains_cy2, 15, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) __PYX_ERR(0, 15, __pyx_L1_error)\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">16</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">17</span>: <span class=\"k\">cdef</span> <span class=\"kt\">Py_ssize_t</span> <span class=\"nf\">idx</span></pre>\n<pre class=\"cython line score-11\" onclick='toggleDiv(this)'>+<span class=\"\">18</span>: <span class=\"k\">cdef</span> <span class=\"kt\">unsigned</span> <span class=\"kt\">int</span> <span class=\"nf\">n</span> <span class=\"o\">=</span> <span class=\"n\">array</span><span class=\"o\">.</span><span class=\"n\">size</span></pre>\n<pre class='cython code score-11 '> __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_array, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_int64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_int64_t, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 18, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_size); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 18, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n __pyx_t_3 = <span class='pyx_c_api'>__Pyx_PyInt_As_unsigned_int</span>(__pyx_t_2); if (unlikely((__pyx_t_3 == (unsigned int)-1) &amp;&amp; <span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 18, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n __pyx_v_n = __pyx_t_3;\n</pre><pre class=\"cython line score-39\" onclick='toggleDiv(this)'>+<span class=\"\">19</span>: <span class=\"k\">cdef</span> <span class=\"kt\">np</span>.<span class=\"kt\">ndarray</span>[<span class=\"kt\">np</span>.<span class=\"nf\">uint8_t</span><span class=\"p\">,</span> <span class=\"nf\">ndim</span><span class=\"o\">=</span><span class=\"mf\">1</span><span class=\"p\">,</span> <span class=\"n\">cast</span><span class=\"o\">=</span><span class=\"bp\">True</span><span class=\"p\">]</span> <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">uint8</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-39 '> __pyx_t_2 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n __pyx_t_1 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyInt_From_unsigned_int</span>(__pyx_v_n); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n __pyx_t_4 = <span class='py_c_api'>PyTuple_New</span>(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_2);\n <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_4, 0, __pyx_t_2);\n __pyx_t_2 = 0;\n __pyx_t_2 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n __pyx_t_5 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_5);\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_5, __pyx_n_s_uint8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_5); __pyx_t_5 = 0;\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_6) &lt; 0) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_1, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 19, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n if (!(likely(((__pyx_t_6) == Py_None) || likely(<span class='pyx_c_api'>__Pyx_TypeTest</span>(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 19, __pyx_L1_error)\n __pyx_t_7 = ((PyArrayObject *)__pyx_t_6);\n {\n __Pyx_BufFmt_StackElem __pyx_stack[1];\n if (unlikely(<span class='pyx_c_api'>__Pyx_GetBufferAndValidate</span>(&amp;__pyx_pybuffernd_result.rcbuffer-&gt;pybuffer, (PyObject*)__pyx_t_7, &amp;__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 1, __pyx_stack) == -1)) {\n __pyx_v_result = ((PyArrayObject *)Py_None); <span class='pyx_macro_api'>__Pyx_INCREF</span>(Py_None); __pyx_pybuffernd_result.rcbuffer-&gt;pybuffer.buf = NULL;\n __PYX_ERR(0, 19, __pyx_L1_error)\n } else {__pyx_pybuffernd_result.diminfo[0].strides = __pyx_pybuffernd_result.rcbuffer-&gt;pybuffer.strides[0]; __pyx_pybuffernd_result.diminfo[0].shape = __pyx_pybuffernd_result.rcbuffer-&gt;pybuffer.shape[0];\n }\n }\n __pyx_t_7 = 0;\n __pyx_v_result = ((PyArrayObject *)__pyx_t_6);\n __pyx_t_6 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">20</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">21</span>: <span class=\"k\">cdef</span> <span class=\"kt\">GEOSContextHandle_t</span> <span class=\"nf\">geos_handle</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">22</span>: <span class=\"k\">cdef</span> <span class=\"kt\">GEOSPreparedGeometry</span> *<span class=\"nf\">geom1</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">23</span>: <span class=\"k\">cdef</span> <span class=\"kt\">GEOSGeometry</span> *<span class=\"nf\">geom2</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">24</span>: <span class=\"k\">cdef</span> <span class=\"kt\">uintptr_t</span> <span class=\"nf\">geos_geom</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">25</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">26</span>: <span class=\"c\"># Prepare the geometry if it hasn&#39;t already been prepared.</span></pre>\n<pre class=\"cython line score-14\" onclick='toggleDiv(this)'>+<span class=\"\">27</span>: <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">geometry</span><span class=\"p\">,</span> <span class=\"n\">shapely</span><span class=\"o\">.</span><span class=\"n\">prepared</span><span class=\"o\">.</span><span class=\"n\">PreparedGeometry</span><span class=\"p\">):</span></pre>\n<pre class='cython code score-14 '> __pyx_t_6 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_shapely); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 27, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_6, __pyx_n_s_prepared); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 27, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_PreparedGeometry); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 27, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n __pyx_t_8 = <span class='py_c_api'>PyObject_IsInstance</span>(__pyx_v_geometry, __pyx_t_6); if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(0, 27, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n __pyx_t_9 = ((!(__pyx_t_8 != 0)) != 0);\n if (__pyx_t_9) {\n/* … */\n }\n</pre><pre class=\"cython line score-33\" onclick='toggleDiv(this)'>+<span class=\"\">28</span>: <span class=\"n\">geometry</span> <span class=\"o\">=</span> <span class=\"n\">shapely</span><span class=\"o\">.</span><span class=\"n\">prepared</span><span class=\"o\">.</span><span class=\"n\">prep</span><span class=\"p\">(</span><span class=\"n\">geometry</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-33 '> __pyx_t_2 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_shapely); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_2, __pyx_n_s_prepared); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n __pyx_t_2 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_4, __pyx_n_s_prep); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n __pyx_t_4 = NULL;\n if (CYTHON_COMPILING_IN_CPYTHON &amp;&amp; likely(<span class='py_c_api'>PyMethod_Check</span>(__pyx_t_2))) {\n __pyx_t_4 = <span class='py_macro_api'>PyMethod_GET_SELF</span>(__pyx_t_2);\n if (likely(__pyx_t_4)) {\n PyObject* function = <span class='py_macro_api'>PyMethod_GET_FUNCTION</span>(__pyx_t_2);\n <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_INCREF</span>(function);\n <span class='pyx_macro_api'>__Pyx_DECREF_SET</span>(__pyx_t_2, function);\n }\n }\n if (!__pyx_t_4) {\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_CallOneArg</span>(__pyx_t_2, __pyx_v_geometry); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n } else {\n __pyx_t_1 = <span class='py_c_api'>PyTuple_New</span>(1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_t_4); <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_1, 0, __pyx_t_4); __pyx_t_4 = NULL;\n <span class='pyx_macro_api'>__Pyx_INCREF</span>(__pyx_v_geometry);\n <span class='refnanny'>__Pyx_GIVEREF</span>(__pyx_v_geometry);\n <span class='py_macro_api'>PyTuple_SET_ITEM</span>(__pyx_t_1, 0+1, __pyx_v_geometry);\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_2, __pyx_t_1, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 28, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n }\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n <span class='pyx_macro_api'>__Pyx_DECREF_SET</span>(__pyx_v_geometry, __pyx_t_6);\n __pyx_t_6 = 0;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">29</span>: </pre>\n<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">30</span>: <span class=\"n\">geos_h</span> <span class=\"o\">=</span> <span class=\"n\">get_geos_context_handle</span><span class=\"p\">()</span></pre>\n<pre class='cython code score-0 '> __pyx_v_geos_h = __pyx_f_46_cython_magic_d349877524f4aa438d2abd5176dcf532_get_geos_context_handle();\n</pre><pre class=\"cython line score-5\" onclick='toggleDiv(this)'>+<span class=\"\">31</span>: <span class=\"n\">geom1</span> <span class=\"o\">=</span> <span class=\"n\">geos_from_prepared</span><span class=\"p\">(</span><span class=\"n\">geometry</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-5 '> __pyx_t_10 = __pyx_f_46_cython_magic_d349877524f4aa438d2abd5176dcf532_geos_from_prepared(__pyx_v_geometry); if (unlikely(<span class='py_c_api'>PyErr_Occurred</span>())) __PYX_ERR(0, 31, __pyx_L1_error)\n __pyx_v_geom1 = __pyx_t_10;\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">32</span>: </pre>\n<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">33</span>: <span class=\"k\">for</span> <span class=\"n\">idx</span> <span class=\"ow\">in</span> <span class=\"nb\">xrange</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">):</span></pre>\n<pre class='cython code score-0 '> __pyx_t_3 = __pyx_v_n;\n for (__pyx_t_11 = 0; __pyx_t_11 &lt; __pyx_t_3; __pyx_t_11+=1) {\n __pyx_v_idx = __pyx_t_11;\n</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">34</span>: <span class=\"n\">geos_geom</span> <span class=\"o\">=</span> <span class=\"n\">array</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">]</span></pre>\n<pre class='cython code score-0 '> __pyx_t_12 = __pyx_v_idx;\n __pyx_v_geos_geom = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_array.data + __pyx_t_12 * __pyx_v_array.strides[0]) )));\n</pre><pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">35</span>: <span class=\"n\">geom2</span> <span class=\"o\">=</span> <span class=\"o\">&lt;</span><span class=\"n\">GEOSGeometry</span> <span class=\"o\">*&gt;</span><span class=\"n\">geos_geom</span></pre>\n<pre class='cython code score-0 '> __pyx_v_geom2 = ((GEOSGeometry *)__pyx_v_geos_geom);\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">36</span>: </pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">37</span>: <span class=\"c\"># Put the result of whether the point is &quot;contained&quot; by the</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">38</span>: <span class=\"c\"># prepared geometry into the result array. </span></pre>\n<pre class=\"cython line score-0\" onclick='toggleDiv(this)'>+<span class=\"\">39</span>: <span class=\"n\">result</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"o\">&lt;</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">uint8_t</span><span class=\"o\">&gt;</span> <span class=\"n\">GEOSPreparedContains_r</span><span class=\"p\">(</span><span class=\"n\">geos_h</span><span class=\"p\">,</span> <span class=\"n\">geom1</span><span class=\"p\">,</span> <span class=\"n\">geom2</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-0 '> __pyx_t_13 = __pyx_v_idx;\n *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint8_t *, __pyx_pybuffernd_result.rcbuffer-&gt;pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_result.diminfo[0].strides) = ((__pyx_t_5numpy_uint8_t)GEOSPreparedContains_r(__pyx_v_geos_h, __pyx_v_geom1, __pyx_v_geom2));\n }\n</pre><pre class=\"cython line score-0\">&#xA0;<span class=\"\">40</span>: <span class=\"c\">#GEOSGeom_destroy_r(geos_h, geom2)</span></pre>\n<pre class=\"cython line score-0\">&#xA0;<span class=\"\">41</span>: </pre>\n<pre class=\"cython line score-23\" onclick='toggleDiv(this)'>+<span class=\"\">42</span>: <span class=\"k\">return</span> <span class=\"n\">result</span><span class=\"o\">.</span><span class=\"n\">view</span><span class=\"p\">(</span><span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">bool</span><span class=\"p\">)</span></pre>\n<pre class='cython code score-23 '> <span class='pyx_macro_api'>__Pyx_XDECREF</span>(__pyx_r);\n __pyx_t_6 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(((PyObject *)__pyx_v_result), __pyx_n_s_view); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 42, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_6);\n __pyx_t_2 = <span class='py_c_api'>PyDict_New</span>(); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 42, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_2);\n __pyx_t_1 = <span class='pyx_c_api'>__Pyx_GetModuleGlobalName</span>(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_1);\n __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_GetAttrStr</span>(__pyx_t_1, __pyx_n_s_bool); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 42, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_1); __pyx_t_1 = 0;\n if (<span class='py_c_api'>PyDict_SetItem</span>(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_4) &lt; 0) __PYX_ERR(0, 42, __pyx_L1_error)\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_4); __pyx_t_4 = 0;\n __pyx_t_4 = <span class='pyx_c_api'>__Pyx_PyObject_Call</span>(__pyx_t_6, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 42, __pyx_L1_error)\n <span class='refnanny'>__Pyx_GOTREF</span>(__pyx_t_4);\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_6); __pyx_t_6 = 0;\n <span class='pyx_macro_api'>__Pyx_DECREF</span>(__pyx_t_2); __pyx_t_2 = 0;\n __pyx_r = __pyx_t_4;\n __pyx_t_4 = 0;\n goto __pyx_L0;\n</pre></div></body></html>"
},
"metadata": {},
"execution_count": 25
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "a2 = np.array([x._geom for x in a])",
"execution_count": 26,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "a2",
"execution_count": 27,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "array([58420512, 57038960, 58072096, ..., 60390032, 60390240, 60390448])"
},
"metadata": {},
"execution_count": 27
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "a2.dtype",
"execution_count": 28,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "dtype('int64')"
},
"metadata": {},
"execution_count": 28
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "res3 = contains_cy2(a2, p)\nres3",
"execution_count": 29,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "array([False, False, False, ..., False, False, False], dtype=bool)"
},
"metadata": {},
"execution_count": 29
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "res3.sum()",
"execution_count": 30,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "89"
},
"metadata": {},
"execution_count": 30
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "np.testing.assert_array_equal(res1, res3)",
"execution_count": 31,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "%timeit contains_cy2(a2, p)",
"execution_count": 32,
"outputs": [
{
"output_type": "stream",
"text": "The slowest run took 23.45 times longer than the fastest. This could mean that an intermediate result is being cached.\n1000 loops, best of 3: 209 µs per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Further massive speed-up !! \n\nFrom 50 ms to 2 ms and now to 0.2 ms -> 250x speed-up !!"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "We have to note that the creation of the array of `geom`pointers also is costly, but this could be cached (if multiple operations are done), and can probably be optimized as well using cython/"
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "%timeit np.array([x._geom for x in a])",
"execution_count": 34,
"outputs": [
{
"output_type": "stream",
"text": "100 loops, best of 3: 3.76 ms per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {
"collapsed": true,
"trusted": true,
"editable": true,
"deletable": true
},
"cell_type": "code",
"source": "",
"execution_count": null,
"outputs": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"name": "dev",
"display_name": "Python 3 (dev)",
"language": "python"
},
"language_info": {
"nbconvert_exporter": "python",
"mimetype": "text/x-python",
"file_extension": ".py",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"name": "python",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment