geoflowkit 0.1.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geoflowkit-0.1.7/LICENSE +21 -0
- geoflowkit-0.1.7/PKG-INFO +284 -0
- geoflowkit-0.1.7/README.md +250 -0
- geoflowkit-0.1.7/geoflowkit/__init__.py +18 -0
- geoflowkit-0.1.7/geoflowkit/base.py +226 -0
- geoflowkit-0.1.7/geoflowkit/clustering/__init__.py +4 -0
- geoflowkit-0.1.7/geoflowkit/clustering/dbscan.py +228 -0
- geoflowkit-0.1.7/geoflowkit/clustering/kmedoid.py +314 -0
- geoflowkit-0.1.7/geoflowkit/flow.py +143 -0
- geoflowkit-0.1.7/geoflowkit/flowdataframe.py +750 -0
- geoflowkit-0.1.7/geoflowkit/flowprocess.py +159 -0
- geoflowkit-0.1.7/geoflowkit/flowseries.py +206 -0
- geoflowkit-0.1.7/geoflowkit/io.py +190 -0
- geoflowkit-0.1.7/geoflowkit/manifold/__init__.py +2 -0
- geoflowkit-0.1.7/geoflowkit/manifold/ftsne/__init__.py +1 -0
- geoflowkit-0.1.7/geoflowkit/manifold/ftsne/ftsne.py +667 -0
- geoflowkit-0.1.7/geoflowkit/manifold/ftsne/utils.py +508 -0
- geoflowkit-0.1.7/geoflowkit/spatial/__init__.py +5 -0
- geoflowkit-0.1.7/geoflowkit/spatial/centrality.py +184 -0
- geoflowkit-0.1.7/geoflowkit/spatial/kl_function.py +219 -0
- geoflowkit-0.1.7/geoflowkit/spatial/utils.py +131 -0
- geoflowkit-0.1.7/geoflowkit.egg-info/PKG-INFO +284 -0
- geoflowkit-0.1.7/geoflowkit.egg-info/SOURCES.txt +29 -0
- geoflowkit-0.1.7/geoflowkit.egg-info/dependency_links.txt +1 -0
- geoflowkit-0.1.7/geoflowkit.egg-info/requires.txt +8 -0
- geoflowkit-0.1.7/geoflowkit.egg-info/top_level.txt +2 -0
- geoflowkit-0.1.7/setup.cfg +4 -0
- geoflowkit-0.1.7/setup.py +30 -0
- geoflowkit-0.1.7/tests/__init__.py +1 -0
- geoflowkit-0.1.7/tests/test_flow_dataframe.py +129 -0
- geoflowkit-0.1.7/tests/test_flow_series.py +84 -0
geoflowkit-0.1.7/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 djw-easy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: geoflowkit
|
|
3
|
+
Version: 0.1.7
|
|
4
|
+
Summary: A package for geospatial flow analysis and visualization
|
|
5
|
+
Home-page: https://github.com/djw-easy/geoflowkit
|
|
6
|
+
Author: GeoFlow Developer
|
|
7
|
+
Author-email: djw@lreis.ac.cn
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.7
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: shapely
|
|
16
|
+
Requires-Dist: numpy
|
|
17
|
+
Requires-Dist: pandas
|
|
18
|
+
Requires-Dist: geopandas>=1.0.1
|
|
19
|
+
Requires-Dist: matplotlib
|
|
20
|
+
Requires-Dist: scikit-learn
|
|
21
|
+
Requires-Dist: tqdm
|
|
22
|
+
Requires-Dist: numba
|
|
23
|
+
Dynamic: author
|
|
24
|
+
Dynamic: author-email
|
|
25
|
+
Dynamic: classifier
|
|
26
|
+
Dynamic: description
|
|
27
|
+
Dynamic: description-content-type
|
|
28
|
+
Dynamic: home-page
|
|
29
|
+
Dynamic: license
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
Dynamic: requires-dist
|
|
32
|
+
Dynamic: requires-python
|
|
33
|
+
Dynamic: summary
|
|
34
|
+
|
|
35
|
+
# GeoFlowKit
|
|
36
|
+
|
|
37
|
+
[](https://badge.fury.io/py/geoflowkit)
|
|
38
|
+
|
|
39
|
+
A Python package for handling and analyzing geographical flow data, extending pandas and geopandas with flow-specific operations.
|
|
40
|
+
|
|
41
|
+
## Overview
|
|
42
|
+
|
|
43
|
+
GeoFlowKit provides `FlowSeries` and `FlowDataFrame` types, which are subclasses of `pandas.Series` and `pandas.DataFrame` respectively. They are designed to work with flow data consisting of origin-destination (OD) pairs, similar to how `geopandas.GeoSeries` and `geopandas.GeoDataFrame` work with geometries.
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install geoflowkit
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or install from source:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Dependencies
|
|
58
|
+
|
|
59
|
+
- shapely
|
|
60
|
+
- numpy
|
|
61
|
+
- pandas
|
|
62
|
+
- geopandas >= 1.0.1
|
|
63
|
+
- matplotlib
|
|
64
|
+
- scikit-learn
|
|
65
|
+
- tqdm
|
|
66
|
+
- numba
|
|
67
|
+
|
|
68
|
+
## Quick Start
|
|
69
|
+
|
|
70
|
+
### Creating Flow Objects
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
import numpy as np
|
|
74
|
+
from geoflowkit import Flow, FlowSeries, FlowDataFrame
|
|
75
|
+
|
|
76
|
+
# Create a single Flow (origin-destination pair)
|
|
77
|
+
flow = Flow([[0, 0], [1, 1]])
|
|
78
|
+
|
|
79
|
+
# Access origin and destination points
|
|
80
|
+
print(flow.o) # POINT (0 0)
|
|
81
|
+
print(flow.d) # POINT (1 1)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Creating FlowSeries
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
# From a list of Flow objects
|
|
88
|
+
fs = FlowSeries([
|
|
89
|
+
Flow([[0, 0], [1, 1]]),
|
|
90
|
+
Flow([[1, 1], [2, 2]]),
|
|
91
|
+
Flow([[2, 2], [3, 3]])
|
|
92
|
+
], crs="EPSG:4326")
|
|
93
|
+
|
|
94
|
+
# From coordinate arrays using flows_from_od
|
|
95
|
+
from geoflowkit import flows_from_od
|
|
96
|
+
|
|
97
|
+
o_points = np.array([[0, 0], [1, 1], [2, 2]])
|
|
98
|
+
d_points = np.array([[1, 1], [2, 2], [3, 3]])
|
|
99
|
+
fs = flows_from_od(o_points, d_points, crs="EPSG:4326")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Creating FlowDataFrame
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# Create a FlowDataFrame with attributes
|
|
106
|
+
data = {
|
|
107
|
+
'id': [1, 2, 3],
|
|
108
|
+
'value': [10, 20, 30],
|
|
109
|
+
'geometry': fs
|
|
110
|
+
}
|
|
111
|
+
fdf = FlowDataFrame(data, crs="EPSG:4326")
|
|
112
|
+
print(fdf)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Reading Data from Files
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
# Read from CSV (specify origin/destination columns)
|
|
119
|
+
fdf = read_csv(
|
|
120
|
+
'flow_data.csv',
|
|
121
|
+
use_cols=['ox', 'oy', 'dx', 'dy'],
|
|
122
|
+
crs='EPSG:4326'
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Read from GeoPackage
|
|
126
|
+
fdf = read_file('flow_data.gpkg', layer='flows')
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Core Features
|
|
130
|
+
|
|
131
|
+
### Flow Properties
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
# Access origin and destination points
|
|
135
|
+
origins = fdf.o # GeoSeries of origin points
|
|
136
|
+
destinations = fdf.d # GeoSeries of destination points
|
|
137
|
+
|
|
138
|
+
# Flow length and angle
|
|
139
|
+
lengths = fdf.length # Distance from origin to destination
|
|
140
|
+
angles = fdf.angle # Direction of flow (radians)
|
|
141
|
+
|
|
142
|
+
# Flow density and volume
|
|
143
|
+
density = fdf.density # Flows per unit area
|
|
144
|
+
volume = fdf.volume # Total bounding area
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Spatial Operations
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
# Calculate pairwise distances between flows
|
|
151
|
+
from geoflowkit import pairwise_distances
|
|
152
|
+
|
|
153
|
+
dist_matrix = pairwise_distances(fdf, distance='max')
|
|
154
|
+
|
|
155
|
+
# Clip flows within a polygon
|
|
156
|
+
clipped = fdf.clip(polygon_mask)
|
|
157
|
+
|
|
158
|
+
# Select flows within bounds
|
|
159
|
+
within_bounds = fdf.within(bounds_box)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Spatial Clustering Scale Detection (K/L Functions)
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
# Calculate K function for spatial clustering
|
|
166
|
+
from geoflowkit import k_func, l_func
|
|
167
|
+
|
|
168
|
+
r_list, kr_list = k_func(fdf, dr=0.1, k=1)
|
|
169
|
+
r_list, lr_list = l_func(fdf, dr=0.1, k=1)
|
|
170
|
+
|
|
171
|
+
# Local L function for individual flows
|
|
172
|
+
from geoflowkit import local_l_func
|
|
173
|
+
|
|
174
|
+
llrs = local_l_func(fdf, r=0.5)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Grid Aggregation
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
# Divide study area into grid and aggregate flows
|
|
181
|
+
gridded = fdf.to_grid(delta_x=0.1, delta_y=0.1)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Visualization
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
# Plot flows as arrows
|
|
188
|
+
ax = fdf.plot(kind='arrow', column='value')
|
|
189
|
+
|
|
190
|
+
# Plot FlowSeries
|
|
191
|
+
ax = fs.plot()
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Flow Clustering
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
# K-medoid clustering
|
|
198
|
+
from geoflowkit import kmedoid
|
|
199
|
+
|
|
200
|
+
labels = kmedoid(fdf, n_clusters=5)
|
|
201
|
+
|
|
202
|
+
# DBSCAN clustering
|
|
203
|
+
from geoflowkit import dbscan
|
|
204
|
+
|
|
205
|
+
labels = dbscan(fdf, eps=0.5, min_samples=5)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Manifold Learning (FTSNE)
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
from geoflowkit import FTSNE
|
|
212
|
+
|
|
213
|
+
# Global interpretability (separate O and D)
|
|
214
|
+
transformer = FTSNE(perplexity=200, learning_rate='auto')
|
|
215
|
+
X_embedded = transformer.fit_transform(
|
|
216
|
+
fdf,
|
|
217
|
+
identity={'o': 0, 'd': 1}
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# Local interpretability (union O and D)
|
|
221
|
+
X_embedded = transformer.fit_transform(
|
|
222
|
+
fdf,
|
|
223
|
+
union={('o', 'd'): (0, 1)}
|
|
224
|
+
)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Location Centrality (I-index)
|
|
228
|
+
|
|
229
|
+
The I-index quantifies the irreplaceability of a location based on flows, combining flow volume and flow length into a single metric following the H-index principle.
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
from geoflowkit.spatial import i_index
|
|
233
|
+
|
|
234
|
+
# Calculate I-index for each zone
|
|
235
|
+
result = i_index(fdf, zones)
|
|
236
|
+
|
|
237
|
+
# Using origin points instead of destination
|
|
238
|
+
result = i_index(fdf, zones, od_type='o')
|
|
239
|
+
|
|
240
|
+
# With custom alpha parameter
|
|
241
|
+
result = i_index(fdf, zones, alpha=1000.0)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**I-index definition**: The I-index of a location is the maximum value of *i* such that at least *i* flows with a length of at least α × *i* meters have reached this location. Higher values indicate more irreplaceable locations that attract many long-distance flows.
|
|
245
|
+
|
|
246
|
+
## Examples
|
|
247
|
+
|
|
248
|
+
Jupyter notebook examples are available in the `examples/` folder:
|
|
249
|
+
|
|
250
|
+
- [basic_usage.ipynb](examples/basic_usage.ipynb) - Basic usage of Flow, FlowSeries, and FlowDataFrame
|
|
251
|
+
- [clustering.ipynb](examples/clustering.ipynb) - K-medoid and DBSCAN clustering for flow data
|
|
252
|
+
- [kl_function.ipynb](examples/kl_function.ipynb) - K/L functions for spatial clustering detection
|
|
253
|
+
- [ft_sne.ipynb](examples/ft_sne.ipynb) - FTSNE manifold learning for flow data
|
|
254
|
+
- [centrality.ipynb](examples/centrality.ipynb) - I-index for location irreplaceability
|
|
255
|
+
|
|
256
|
+
## API Reference
|
|
257
|
+
|
|
258
|
+
### Classes
|
|
259
|
+
|
|
260
|
+
- `Flow`: Geometry object representing an origin-destination pair
|
|
261
|
+
- `FlowSeries`: pandas Series subclass for storing Flow objects
|
|
262
|
+
- `FlowDataFrame`: pandas DataFrame subclass with Flow geometry column
|
|
263
|
+
|
|
264
|
+
### Key Functions
|
|
265
|
+
|
|
266
|
+
- `flows_from_od(o, d, crs=None)`: Create FlowSeries from coordinate arrays
|
|
267
|
+
- `flows_from_geometry(geometry, crs=None)`: Create FlowSeries from geometry objects
|
|
268
|
+
- `read_csv(file_path, use_cols, crs=None, **kwargs)`: Read flow data from CSV
|
|
269
|
+
- `read_file(file_path, **kwargs)`: Read flow data from vector file
|
|
270
|
+
- `pairwise_distances(fdf, distance='max', ...)`: Calculate flow distance matrix
|
|
271
|
+
- `k_func(fdf, dr, k=1, distance='max', ...)`: K function for spatial clustering detection
|
|
272
|
+
- `l_func(fdf, dr, k=1, distance='max', ...)`: L function for spatial clustering detection
|
|
273
|
+
- `local_l_func(fdf, r, distance='max', ...)`: Local L function for individual flows
|
|
274
|
+
- `kmedoid(fdf, n_clusters=5, ...)`: K-medoid clustering for flows
|
|
275
|
+
- `dbscan(fdf, eps=0.5, min_samples=5, ...)`: DBSCAN clustering for flows
|
|
276
|
+
- `i_index(fdf, zones, alpha=None, od_type='d', ...)`: I-index for location irreplaceability
|
|
277
|
+
|
|
278
|
+
## License
|
|
279
|
+
|
|
280
|
+
GeoFlowKit is licensed under the MIT License.
|
|
281
|
+
|
|
282
|
+
## Contact
|
|
283
|
+
|
|
284
|
+
For questions or feedback: djw@lreis.ac.cn
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# GeoFlowKit
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/geoflowkit)
|
|
4
|
+
|
|
5
|
+
A Python package for handling and analyzing geographical flow data, extending pandas and geopandas with flow-specific operations.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
GeoFlowKit provides `FlowSeries` and `FlowDataFrame` types, which are subclasses of `pandas.Series` and `pandas.DataFrame` respectively. They are designed to work with flow data consisting of origin-destination (OD) pairs, similar to how `geopandas.GeoSeries` and `geopandas.GeoDataFrame` work with geometries.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install geoflowkit
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Or install from source:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install .
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Dependencies
|
|
24
|
+
|
|
25
|
+
- shapely
|
|
26
|
+
- numpy
|
|
27
|
+
- pandas
|
|
28
|
+
- geopandas >= 1.0.1
|
|
29
|
+
- matplotlib
|
|
30
|
+
- scikit-learn
|
|
31
|
+
- tqdm
|
|
32
|
+
- numba
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### Creating Flow Objects
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import numpy as np
|
|
40
|
+
from geoflowkit import Flow, FlowSeries, FlowDataFrame
|
|
41
|
+
|
|
42
|
+
# Create a single Flow (origin-destination pair)
|
|
43
|
+
flow = Flow([[0, 0], [1, 1]])
|
|
44
|
+
|
|
45
|
+
# Access origin and destination points
|
|
46
|
+
print(flow.o) # POINT (0 0)
|
|
47
|
+
print(flow.d) # POINT (1 1)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Creating FlowSeries
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
# From a list of Flow objects
|
|
54
|
+
fs = FlowSeries([
|
|
55
|
+
Flow([[0, 0], [1, 1]]),
|
|
56
|
+
Flow([[1, 1], [2, 2]]),
|
|
57
|
+
Flow([[2, 2], [3, 3]])
|
|
58
|
+
], crs="EPSG:4326")
|
|
59
|
+
|
|
60
|
+
# From coordinate arrays using flows_from_od
|
|
61
|
+
from geoflowkit import flows_from_od
|
|
62
|
+
|
|
63
|
+
o_points = np.array([[0, 0], [1, 1], [2, 2]])
|
|
64
|
+
d_points = np.array([[1, 1], [2, 2], [3, 3]])
|
|
65
|
+
fs = flows_from_od(o_points, d_points, crs="EPSG:4326")
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Creating FlowDataFrame
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
# Create a FlowDataFrame with attributes
|
|
72
|
+
data = {
|
|
73
|
+
'id': [1, 2, 3],
|
|
74
|
+
'value': [10, 20, 30],
|
|
75
|
+
'geometry': fs
|
|
76
|
+
}
|
|
77
|
+
fdf = FlowDataFrame(data, crs="EPSG:4326")
|
|
78
|
+
print(fdf)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Reading Data from Files
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
# Read from CSV (specify origin/destination columns)
|
|
85
|
+
fdf = read_csv(
|
|
86
|
+
'flow_data.csv',
|
|
87
|
+
use_cols=['ox', 'oy', 'dx', 'dy'],
|
|
88
|
+
crs='EPSG:4326'
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Read from GeoPackage
|
|
92
|
+
fdf = read_file('flow_data.gpkg', layer='flows')
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Core Features
|
|
96
|
+
|
|
97
|
+
### Flow Properties
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
# Access origin and destination points
|
|
101
|
+
origins = fdf.o # GeoSeries of origin points
|
|
102
|
+
destinations = fdf.d # GeoSeries of destination points
|
|
103
|
+
|
|
104
|
+
# Flow length and angle
|
|
105
|
+
lengths = fdf.length # Distance from origin to destination
|
|
106
|
+
angles = fdf.angle # Direction of flow (radians)
|
|
107
|
+
|
|
108
|
+
# Flow density and volume
|
|
109
|
+
density = fdf.density # Flows per unit area
|
|
110
|
+
volume = fdf.volume # Total bounding area
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Spatial Operations
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
# Calculate pairwise distances between flows
|
|
117
|
+
from geoflowkit import pairwise_distances
|
|
118
|
+
|
|
119
|
+
dist_matrix = pairwise_distances(fdf, distance='max')
|
|
120
|
+
|
|
121
|
+
# Clip flows within a polygon
|
|
122
|
+
clipped = fdf.clip(polygon_mask)
|
|
123
|
+
|
|
124
|
+
# Select flows within bounds
|
|
125
|
+
within_bounds = fdf.within(bounds_box)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Spatial Clustering Scale Detection (K/L Functions)
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# Calculate K function for spatial clustering
|
|
132
|
+
from geoflowkit import k_func, l_func
|
|
133
|
+
|
|
134
|
+
r_list, kr_list = k_func(fdf, dr=0.1, k=1)
|
|
135
|
+
r_list, lr_list = l_func(fdf, dr=0.1, k=1)
|
|
136
|
+
|
|
137
|
+
# Local L function for individual flows
|
|
138
|
+
from geoflowkit import local_l_func
|
|
139
|
+
|
|
140
|
+
llrs = local_l_func(fdf, r=0.5)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Grid Aggregation
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
# Divide study area into grid and aggregate flows
|
|
147
|
+
gridded = fdf.to_grid(delta_x=0.1, delta_y=0.1)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Visualization
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
# Plot flows as arrows
|
|
154
|
+
ax = fdf.plot(kind='arrow', column='value')
|
|
155
|
+
|
|
156
|
+
# Plot FlowSeries
|
|
157
|
+
ax = fs.plot()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Flow Clustering
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
# K-medoid clustering
|
|
164
|
+
from geoflowkit import kmedoid
|
|
165
|
+
|
|
166
|
+
labels = kmedoid(fdf, n_clusters=5)
|
|
167
|
+
|
|
168
|
+
# DBSCAN clustering
|
|
169
|
+
from geoflowkit import dbscan
|
|
170
|
+
|
|
171
|
+
labels = dbscan(fdf, eps=0.5, min_samples=5)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Manifold Learning (FTSNE)
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from geoflowkit import FTSNE
|
|
178
|
+
|
|
179
|
+
# Global interpretability (separate O and D)
|
|
180
|
+
transformer = FTSNE(perplexity=200, learning_rate='auto')
|
|
181
|
+
X_embedded = transformer.fit_transform(
|
|
182
|
+
fdf,
|
|
183
|
+
identity={'o': 0, 'd': 1}
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Local interpretability (union O and D)
|
|
187
|
+
X_embedded = transformer.fit_transform(
|
|
188
|
+
fdf,
|
|
189
|
+
union={('o', 'd'): (0, 1)}
|
|
190
|
+
)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Location Centrality (I-index)
|
|
194
|
+
|
|
195
|
+
The I-index quantifies the irreplaceability of a location based on flows, combining flow volume and flow length into a single metric following the H-index principle.
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from geoflowkit.spatial import i_index
|
|
199
|
+
|
|
200
|
+
# Calculate I-index for each zone
|
|
201
|
+
result = i_index(fdf, zones)
|
|
202
|
+
|
|
203
|
+
# Using origin points instead of destination
|
|
204
|
+
result = i_index(fdf, zones, od_type='o')
|
|
205
|
+
|
|
206
|
+
# With custom alpha parameter
|
|
207
|
+
result = i_index(fdf, zones, alpha=1000.0)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**I-index definition**: The I-index of a location is the maximum value of *i* such that at least *i* flows with a length of at least α × *i* meters have reached this location. Higher values indicate more irreplaceable locations that attract many long-distance flows.
|
|
211
|
+
|
|
212
|
+
## Examples
|
|
213
|
+
|
|
214
|
+
Jupyter notebook examples are available in the `examples/` folder:
|
|
215
|
+
|
|
216
|
+
- [basic_usage.ipynb](examples/basic_usage.ipynb) - Basic usage of Flow, FlowSeries, and FlowDataFrame
|
|
217
|
+
- [clustering.ipynb](examples/clustering.ipynb) - K-medoid and DBSCAN clustering for flow data
|
|
218
|
+
- [kl_function.ipynb](examples/kl_function.ipynb) - K/L functions for spatial clustering detection
|
|
219
|
+
- [ft_sne.ipynb](examples/ft_sne.ipynb) - FTSNE manifold learning for flow data
|
|
220
|
+
- [centrality.ipynb](examples/centrality.ipynb) - I-index for location irreplaceability
|
|
221
|
+
|
|
222
|
+
## API Reference
|
|
223
|
+
|
|
224
|
+
### Classes
|
|
225
|
+
|
|
226
|
+
- `Flow`: Geometry object representing an origin-destination pair
|
|
227
|
+
- `FlowSeries`: pandas Series subclass for storing Flow objects
|
|
228
|
+
- `FlowDataFrame`: pandas DataFrame subclass with Flow geometry column
|
|
229
|
+
|
|
230
|
+
### Key Functions
|
|
231
|
+
|
|
232
|
+
- `flows_from_od(o, d, crs=None)`: Create FlowSeries from coordinate arrays
|
|
233
|
+
- `flows_from_geometry(geometry, crs=None)`: Create FlowSeries from geometry objects
|
|
234
|
+
- `read_csv(file_path, use_cols, crs=None, **kwargs)`: Read flow data from CSV
|
|
235
|
+
- `read_file(file_path, **kwargs)`: Read flow data from vector file
|
|
236
|
+
- `pairwise_distances(fdf, distance='max', ...)`: Calculate flow distance matrix
|
|
237
|
+
- `k_func(fdf, dr, k=1, distance='max', ...)`: K function for spatial clustering detection
|
|
238
|
+
- `l_func(fdf, dr, k=1, distance='max', ...)`: L function for spatial clustering detection
|
|
239
|
+
- `local_l_func(fdf, r, distance='max', ...)`: Local L function for individual flows
|
|
240
|
+
- `kmedoid(fdf, n_clusters=5, ...)`: K-medoid clustering for flows
|
|
241
|
+
- `dbscan(fdf, eps=0.5, min_samples=5, ...)`: DBSCAN clustering for flows
|
|
242
|
+
- `i_index(fdf, zones, alpha=None, od_type='d', ...)`: I-index for location irreplaceability
|
|
243
|
+
|
|
244
|
+
## License
|
|
245
|
+
|
|
246
|
+
GeoFlowKit is licensed under the MIT License.
|
|
247
|
+
|
|
248
|
+
## Contact
|
|
249
|
+
|
|
250
|
+
For questions or feedback: djw@lreis.ac.cn
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
__version__ = "0.1.6"
|
|
2
|
+
|
|
3
|
+
from geoflowkit.flow import Flow
|
|
4
|
+
from geoflowkit.flowseries import FlowSeries
|
|
5
|
+
from geoflowkit.flowdataframe import FlowDataFrame
|
|
6
|
+
from geoflowkit.flowprocess import pairwise_distances
|
|
7
|
+
from geoflowkit.io import read_csv, read_file, flows_from_od, flows_from_geometry
|
|
8
|
+
|
|
9
|
+
from geoflowkit.spatial.utils import second_order_density
|
|
10
|
+
from geoflowkit.spatial.kl_function import k_func, l_func, local_l_func
|
|
11
|
+
|
|
12
|
+
from geoflowkit.clustering import (
|
|
13
|
+
KMedoidFlow, kmedoid,
|
|
14
|
+
DBSCANFlow, dbscan
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from geoflowkit.manifold import FTSNE
|
|
18
|
+
|