bcdata 0.10.2__tar.gz → 0.13.0__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.
Files changed (31) hide show
  1. {bcdata-0.10.2/bcdata.egg-info → bcdata-0.13.0}/PKG-INFO +57 -48
  2. {bcdata-0.10.2 → bcdata-0.13.0}/README.md +37 -26
  3. bcdata-0.13.0/pyproject.toml +55 -0
  4. bcdata-0.13.0/src/bcdata/__init__.py +27 -0
  5. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata/bc2pg.py +43 -75
  6. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata/bcdc.py +46 -59
  7. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata/cli.py +39 -20
  8. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata/database.py +25 -16
  9. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata/wcs.py +2 -8
  10. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata/wfs.py +69 -41
  11. {bcdata-0.10.2 → bcdata-0.13.0/src/bcdata.egg-info}/PKG-INFO +57 -48
  12. bcdata-0.13.0/src/bcdata.egg-info/SOURCES.txt +21 -0
  13. bcdata-0.13.0/src/bcdata.egg-info/requires.txt +13 -0
  14. {bcdata-0.10.2 → bcdata-0.13.0}/tests/test_bc2pg.py +33 -12
  15. {bcdata-0.10.2 → bcdata-0.13.0}/tests/test_bcdc.py +31 -2
  16. {bcdata-0.10.2 → bcdata-0.13.0}/tests/test_wcs.py +3 -6
  17. {bcdata-0.10.2 → bcdata-0.13.0}/tests/test_wfs.py +22 -16
  18. bcdata-0.10.2/CHANGES.txt +0 -298
  19. bcdata-0.10.2/bcdata/__init__.py +0 -18
  20. bcdata-0.10.2/bcdata.egg-info/SOURCES.txt +0 -25
  21. bcdata-0.10.2/bcdata.egg-info/not-zip-safe +0 -1
  22. bcdata-0.10.2/bcdata.egg-info/requires.txt +0 -13
  23. bcdata-0.10.2/pyproject.toml +0 -16
  24. bcdata-0.10.2/requirements.txt +0 -8
  25. bcdata-0.10.2/setup.py +0 -55
  26. {bcdata-0.10.2 → bcdata-0.13.0}/LICENSE.txt +0 -0
  27. {bcdata-0.10.2 → bcdata-0.13.0}/setup.cfg +0 -0
  28. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata.egg-info/dependency_links.txt +0 -0
  29. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata.egg-info/entry_points.txt +0 -0
  30. {bcdata-0.10.2 → bcdata-0.13.0/src}/bcdata.egg-info/top_level.txt +0 -0
  31. {bcdata-0.10.2 → bcdata-0.13.0}/tests/test_cli.py +0 -0
@@ -1,36 +1,34 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bcdata
3
- Version: 0.10.2
4
- Summary: Python tools for quick access to DataBC geo-data available via WFS
5
- Home-page: https://github.com/smnorris/bcdata
6
- Author: Simon Norris
7
- Author-email: snorris@hillcrestgeo.ca
8
- License: MIT
9
- Keywords: gis geospatial data BC DataBC download "Britsh Columbia"
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Intended Audience :: Developers
12
- Classifier: Intended Audience :: Science/Research
13
- Classifier: Operating System :: OS Independent
3
+ Version: 0.13.0
4
+ Summary: Download open data, monitor and report on changes
5
+ Author-email: Simon Norris <snorris@hillcrestgeo.ca>
6
+ Project-URL: Homepage, https://github.com/smnorris/bcdata
7
+ Project-URL: Issues, https://github.com/smnorris/bcdata
8
+ Classifier: Development Status :: 1 - Planning
14
9
  Classifier: Programming Language :: Python :: 3.9
15
10
  Classifier: Programming Language :: Python :: 3.10
16
11
  Classifier: Programming Language :: Python :: 3.11
17
12
  Classifier: Programming Language :: Python :: 3.12
18
- Classifier: Topic :: Utilities
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: License :: OSI Approved :: MIT License
19
15
  Classifier: Topic :: Scientific/Engineering :: GIS
16
+ Classifier: Operating System :: OS Independent
17
+ Requires-Python: >=3.9
20
18
  Description-Content-Type: text/markdown
21
19
  License-File: LICENSE.txt
22
- Requires-Dist: geoalchemy2==0.14.*
23
- Requires-Dist: geopandas==0.14.*
24
- Requires-Dist: owslib==0.29.*
25
- Requires-Dist: psycopg2-binary==2.9.*
26
- Requires-Dist: rasterio==1.3.*
27
- Requires-Dist: requests==2.31.*
28
- Requires-Dist: sqlalchemy==2.0.*
29
- Requires-Dist: stamina==23.2.*
20
+ Requires-Dist: geoalchemy2
21
+ Requires-Dist: geopandas
22
+ Requires-Dist: owslib
23
+ Requires-Dist: psycopg2-binary
24
+ Requires-Dist: rasterio
25
+ Requires-Dist: requests
26
+ Requires-Dist: sqlalchemy
27
+ Requires-Dist: stamina
30
28
  Provides-Extra: test
31
- Requires-Dist: pytest>=3; extra == "test"
29
+ Requires-Dist: pytest; extra == "test"
32
30
  Requires-Dist: pre-commit; extra == "test"
33
- Requires-Dist: requests_mock; extra == "test"
31
+ Requires-Dist: requests-mock; extra == "test"
34
32
 
35
33
  # bcdata
36
34
 
@@ -43,7 +41,9 @@ There is a [wealth of British Columbia geographic information available as open
43
41
  data](https://catalogue.data.gov.bc.ca/dataset?download_audience=Public),
44
42
  but direct file download urls are not available and the syntax to accesss WFS via `ogr2ogr` and/or `curl/wget` can be awkward.
45
43
 
46
- This Python module and CLI attempts to simplify downloads of BC geographic data and smoothly integrate with PostGIS and Python GIS tools like `geopandas`, `fiona` and `rasterio`. As noted above, the module is an interface only to geographic data [avialable via WFS/WCS](https://bcgov.github.io/data-publication/pages/tips_tricks_webservices.html) - to work with other BC open data, use the [bcdata R package](https://github.com/bcgov/bcdata).
44
+ This tool attempts to simplify downloads of BC geographic data and smoothly integrate with PostGIS and Python GIS tools like `geopandas`, `fiona` and `rasterio`. As noted above, the module is an interface only to geographic data [avialable via WFS/WCS](https://bcgov.github.io/data-publication/pages/tips_tricks_webservices.html) - to work with other BC open data, use the [bcdata R package](https://github.com/bcgov/bcdata).
45
+
46
+ Note that this tool depends on BC Open Geospatial Web Services API at [openmaps.gov.bc.ca](https://openmaps.gov.bc.ca/geo/pub/ows?service=WFS&request=Getcapabilities) and the [BC Data Catalogue API](https://catalogue.data.gov.bc.ca/dataset/bc-data-catalogue-api). If downloads are failing, consult the [BCGov Data Systems and Services uptime monitor](https://uptime.com/statuspage/bcgov-dss).
47
47
 
48
48
  **Disclaimer**
49
49
  *It is the user's responsibility to check the licensing for any downloads, data are generally licensed as [OGL-BC](http://www2.gov.bc.ca/gov/content/governments/about-the-bc-government/databc/open-data/open-government-license-bc)*
@@ -153,25 +153,30 @@ Usage: bcdata bc2pg [OPTIONS] DATASET
153
153
 
154
154
  Download a DataBC WFS layer to postgres
155
155
 
156
- $ bcdata bc2pg bc-airports --db_url postgresql://postgres:postgres@localhost:5432/postgis
156
+ $ bcdata bc2pg whse_imagery_and_base_maps.gsr_airports_svw
157
157
 
158
158
  Options:
159
- -db, --db_url TEXT Target database url, defaults to $DATABASE_URL
160
- environment variable if set
161
- --table TEXT Destination table name
162
- --schema TEXT Destination schema name
163
- --geometry_type TEXT Spatial type of geometry column
164
- --query TEXT A valid CQL or ECQL query
165
- -c, --count INTEGER Total number of features to load
166
- -k, --primary_key TEXT Primary key of dataset
167
- -s, --sortby TEXT Name of sort field
168
- -e, --schema_only Create empty table from catalogue schema
169
- -a, --append Append to existing table
170
- -r, --refresh Truncate from existing table before load
171
- -t, --no_timestamp Do not log download to bcdata.log
172
- -v, --verbose Increase verbosity.
173
- -q, --quiet Decrease verbosity.
174
- --help Show this message and exit.
159
+ -db, --db_url TEXT Target database url, defaults to
160
+ $DATABASE_URL environment variable if set
161
+ --table TEXT Destination table name
162
+ --schema TEXT Destination schema name
163
+ --geometry_type TEXT Spatial type of geometry column
164
+ --query TEXT A valid CQL or ECQL query
165
+ --bounds TEXT Bounds: "left bottom right top" or "[left,
166
+ bottom, right, top]". Coordinates are BC
167
+ Albers (default) or --bounds_crs
168
+ --bounds-crs, --bounds_crs TEXT
169
+ CRS of provided bounds
170
+ -c, --count INTEGER Total number of features to load
171
+ -k, --primary_key TEXT Primary key of dataset
172
+ -s, --sortby TEXT Name of sort field
173
+ -e, --schema_only Create empty table from catalogue schema
174
+ -a, --append Append to existing table
175
+ -r, --refresh Truncate from existing table before load
176
+ -t, --no_timestamp Do not log download to bcdata.log
177
+ -v, --verbose Increase verbosity.
178
+ -q, --quiet Decrease verbosity.
179
+ --help Show this message and exit.
175
180
  ```
176
181
 
177
182
  #### cat
@@ -332,7 +337,7 @@ Describe a dataset. Note that if we know the id of a dataset, we can use that ra
332
337
 
333
338
  The JSON output can be manipulated with [jq](https://stedolan.github.io/jq/). For example, to show only the fields available in the dataset:
334
339
 
335
- $ bcdata info bc-airports | jq '.schema.properties'
340
+ $ bcdata info bc-airports | jq '.schema'
336
341
  {
337
342
  "CUSTODIAN_ORG_DESCRIPTION": "string",
338
343
  "BUSINESS_CATEGORY_CLASS": "string",
@@ -360,6 +365,11 @@ Save a layer to a geopackage in BC Albers:
360
365
 
361
366
  Note that this will not work if the source data has mixed geometry types.
362
367
 
368
+ Load to parquet on s3:
369
+
370
+ $ bcdata dump bc-airports \
371
+ | ogr2ogr -f Parquet /vsis3/$BUCKET/airports.parquet -s_srs EPSG:4326 -t_srs EPSG:3005 /vsistdin/
372
+
363
373
  Load data to postgres and run a spatial query:
364
374
 
365
375
  $ bcdata bc2pg bc-airports \
@@ -406,13 +416,12 @@ Load data to postgres and run a spatial query:
406
416
 
407
417
  Create virtualenv and install `bcdata` in development mode:
408
418
 
409
- $ mkdir bcdata_env
410
- $ virtualenv bcdata_env
411
- $ source bcdata_env/bin/activate
412
- (bcdata_env)$ git clone git@github.com:smnorris/bcdata.git
413
- (bcdata_env)$ cd bcdata
414
- (bcdata_env)$ pip install -e .[test]
415
- (bcdata_env)$ py.test
419
+ $ git clone git@github.com:smnorris/bcdata.git
420
+ $ cd bcdata
421
+ $ python -m venv .venv
422
+ $ source .venv/bin/activate
423
+ (.venv)$ pip install -e .[test]
424
+ (.venv)$ py.test
416
425
 
417
426
 
418
427
  ## Other implementations
@@ -9,7 +9,9 @@ There is a [wealth of British Columbia geographic information available as open
9
9
  data](https://catalogue.data.gov.bc.ca/dataset?download_audience=Public),
10
10
  but direct file download urls are not available and the syntax to accesss WFS via `ogr2ogr` and/or `curl/wget` can be awkward.
11
11
 
12
- This Python module and CLI attempts to simplify downloads of BC geographic data and smoothly integrate with PostGIS and Python GIS tools like `geopandas`, `fiona` and `rasterio`. As noted above, the module is an interface only to geographic data [avialable via WFS/WCS](https://bcgov.github.io/data-publication/pages/tips_tricks_webservices.html) - to work with other BC open data, use the [bcdata R package](https://github.com/bcgov/bcdata).
12
+ This tool attempts to simplify downloads of BC geographic data and smoothly integrate with PostGIS and Python GIS tools like `geopandas`, `fiona` and `rasterio`. As noted above, the module is an interface only to geographic data [avialable via WFS/WCS](https://bcgov.github.io/data-publication/pages/tips_tricks_webservices.html) - to work with other BC open data, use the [bcdata R package](https://github.com/bcgov/bcdata).
13
+
14
+ Note that this tool depends on BC Open Geospatial Web Services API at [openmaps.gov.bc.ca](https://openmaps.gov.bc.ca/geo/pub/ows?service=WFS&request=Getcapabilities) and the [BC Data Catalogue API](https://catalogue.data.gov.bc.ca/dataset/bc-data-catalogue-api). If downloads are failing, consult the [BCGov Data Systems and Services uptime monitor](https://uptime.com/statuspage/bcgov-dss).
13
15
 
14
16
  **Disclaimer**
15
17
  *It is the user's responsibility to check the licensing for any downloads, data are generally licensed as [OGL-BC](http://www2.gov.bc.ca/gov/content/governments/about-the-bc-government/databc/open-data/open-government-license-bc)*
@@ -119,25 +121,30 @@ Usage: bcdata bc2pg [OPTIONS] DATASET
119
121
 
120
122
  Download a DataBC WFS layer to postgres
121
123
 
122
- $ bcdata bc2pg bc-airports --db_url postgresql://postgres:postgres@localhost:5432/postgis
124
+ $ bcdata bc2pg whse_imagery_and_base_maps.gsr_airports_svw
123
125
 
124
126
  Options:
125
- -db, --db_url TEXT Target database url, defaults to $DATABASE_URL
126
- environment variable if set
127
- --table TEXT Destination table name
128
- --schema TEXT Destination schema name
129
- --geometry_type TEXT Spatial type of geometry column
130
- --query TEXT A valid CQL or ECQL query
131
- -c, --count INTEGER Total number of features to load
132
- -k, --primary_key TEXT Primary key of dataset
133
- -s, --sortby TEXT Name of sort field
134
- -e, --schema_only Create empty table from catalogue schema
135
- -a, --append Append to existing table
136
- -r, --refresh Truncate from existing table before load
137
- -t, --no_timestamp Do not log download to bcdata.log
138
- -v, --verbose Increase verbosity.
139
- -q, --quiet Decrease verbosity.
140
- --help Show this message and exit.
127
+ -db, --db_url TEXT Target database url, defaults to
128
+ $DATABASE_URL environment variable if set
129
+ --table TEXT Destination table name
130
+ --schema TEXT Destination schema name
131
+ --geometry_type TEXT Spatial type of geometry column
132
+ --query TEXT A valid CQL or ECQL query
133
+ --bounds TEXT Bounds: "left bottom right top" or "[left,
134
+ bottom, right, top]". Coordinates are BC
135
+ Albers (default) or --bounds_crs
136
+ --bounds-crs, --bounds_crs TEXT
137
+ CRS of provided bounds
138
+ -c, --count INTEGER Total number of features to load
139
+ -k, --primary_key TEXT Primary key of dataset
140
+ -s, --sortby TEXT Name of sort field
141
+ -e, --schema_only Create empty table from catalogue schema
142
+ -a, --append Append to existing table
143
+ -r, --refresh Truncate from existing table before load
144
+ -t, --no_timestamp Do not log download to bcdata.log
145
+ -v, --verbose Increase verbosity.
146
+ -q, --quiet Decrease verbosity.
147
+ --help Show this message and exit.
141
148
  ```
142
149
 
143
150
  #### cat
@@ -298,7 +305,7 @@ Describe a dataset. Note that if we know the id of a dataset, we can use that ra
298
305
 
299
306
  The JSON output can be manipulated with [jq](https://stedolan.github.io/jq/). For example, to show only the fields available in the dataset:
300
307
 
301
- $ bcdata info bc-airports | jq '.schema.properties'
308
+ $ bcdata info bc-airports | jq '.schema'
302
309
  {
303
310
  "CUSTODIAN_ORG_DESCRIPTION": "string",
304
311
  "BUSINESS_CATEGORY_CLASS": "string",
@@ -326,6 +333,11 @@ Save a layer to a geopackage in BC Albers:
326
333
 
327
334
  Note that this will not work if the source data has mixed geometry types.
328
335
 
336
+ Load to parquet on s3:
337
+
338
+ $ bcdata dump bc-airports \
339
+ | ogr2ogr -f Parquet /vsis3/$BUCKET/airports.parquet -s_srs EPSG:4326 -t_srs EPSG:3005 /vsistdin/
340
+
329
341
  Load data to postgres and run a spatial query:
330
342
 
331
343
  $ bcdata bc2pg bc-airports \
@@ -372,13 +384,12 @@ Load data to postgres and run a spatial query:
372
384
 
373
385
  Create virtualenv and install `bcdata` in development mode:
374
386
 
375
- $ mkdir bcdata_env
376
- $ virtualenv bcdata_env
377
- $ source bcdata_env/bin/activate
378
- (bcdata_env)$ git clone git@github.com:smnorris/bcdata.git
379
- (bcdata_env)$ cd bcdata
380
- (bcdata_env)$ pip install -e .[test]
381
- (bcdata_env)$ py.test
387
+ $ git clone git@github.com:smnorris/bcdata.git
388
+ $ cd bcdata
389
+ $ python -m venv .venv
390
+ $ source .venv/bin/activate
391
+ (.venv)$ pip install -e .[test]
392
+ (.venv)$ py.test
382
393
 
383
394
 
384
395
  ## Other implementations
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "bcdata"
7
+ dynamic = ["version"]
8
+ readme = "README.md"
9
+ license = {file = "LICENSE"}
10
+ authors = [
11
+ {name="Simon Norris", email="snorris@hillcrestgeo.ca"},
12
+ ]
13
+ description = "Download open data, monitor and report on changes"
14
+ requires-python = ">=3.9"
15
+ classifiers = [
16
+ "Development Status :: 1 - Planning",
17
+ "Programming Language :: Python :: 3.9",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "License :: OSI Approved :: MIT License",
23
+ "Topic :: Scientific/Engineering :: GIS",
24
+ "Operating System :: OS Independent"
25
+ ]
26
+ dependencies = [
27
+ "geoalchemy2",
28
+ "geopandas",
29
+ "owslib",
30
+ "psycopg2-binary",
31
+ "rasterio",
32
+ "requests",
33
+ "sqlalchemy",
34
+ "stamina"
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ test = [
39
+ "pytest",
40
+ "pre-commit",
41
+ "requests-mock"
42
+ ]
43
+
44
+ [project.scripts]
45
+ bcdata = "bcdata.cli:cli"
46
+
47
+ [project.urls]
48
+ Homepage = "https://github.com/smnorris/bcdata"
49
+ Issues = "https://github.com/smnorris/bcdata"
50
+
51
+ [tool.setuptools.dynamic]
52
+ version = {attr = "bcdata.__version__"}
53
+
54
+ [tool.ruff]
55
+ line-length = 100
@@ -0,0 +1,27 @@
1
+ import requests
2
+
3
+ from .bc2pg import bc2pg as bc2pg
4
+ from .bcdc import get_table_definition as get_table_definition
5
+ from .bcdc import get_table_name as get_table_name
6
+ from .wcs import get_dem as get_dem
7
+ from .wfs import define_requests as define_requests
8
+ from .wfs import get_count as get_count
9
+ from .wfs import get_data as get_data
10
+ from .wfs import get_features as get_features
11
+ from .wfs import get_sortkey as get_sortkey
12
+ from .wfs import list_tables as list_tables
13
+ from .wfs import validate_name as validate_name
14
+
15
+ PRIMARY_KEY_DB_URL = "https://raw.githubusercontent.com/smnorris/bcdata/main/data/primary_keys.json"
16
+
17
+ # BCDC does not indicate which column in the schema is the primary key.
18
+ # In this absence, bcdata maintains its own dictionary of {table: primary_key},
19
+ # served via github. Retrieve the dict with this function"""
20
+ response = requests.get(PRIMARY_KEY_DB_URL)
21
+ if response.status_code == 200:
22
+ primary_keys = response.json()
23
+ else:
24
+ raise Exception(f"Failed to download primary key database at {PRIMARY_KEY_DB_URL}")
25
+ primary_keys = {}
26
+
27
+ __version__ = "0.13.0"
@@ -1,12 +1,6 @@
1
- import json
2
1
  import logging
3
- import os
4
2
 
5
- import geopandas as gpd
6
3
  import numpy
7
- import stamina
8
- from geoalchemy2 import Geometry
9
- import requests
10
4
  from shapely.geometry.linestring import LineString
11
5
  from shapely.geometry.multilinestring import MultiLineString
12
6
  from shapely.geometry.multipoint import MultiPoint
@@ -34,19 +28,6 @@ SUPPORTED_TYPES = [
34
28
  ]
35
29
 
36
30
 
37
- def get_primary_keys():
38
- """download primary key data file"""
39
- response = requests.get(bcdata.PRIMARY_KEY_DB_URL)
40
- if response.status_code == 200:
41
- primary_keys = response.json()
42
- else:
43
- log.warning(
44
- f"Failed to download primary key database at {bcdata.PRIMARY_KEY_DB_URL}"
45
- )
46
- primary_keys = {}
47
- return primary_keys
48
-
49
-
50
31
  def bc2pg( # noqa: C901
51
32
  dataset,
52
33
  db_url,
@@ -54,12 +35,15 @@ def bc2pg( # noqa: C901
54
35
  schema=None,
55
36
  geometry_type=None,
56
37
  query=None,
38
+ bounds=None,
39
+ bounds_crs="EPSG:3005",
57
40
  count=None,
58
41
  sortby=None,
59
42
  primary_key=None,
60
43
  timestamp=True,
61
44
  schema_only=False,
62
45
  append=False,
46
+ refresh=False,
63
47
  ):
64
48
  """Request table definition from bcdc and replicate in postgres"""
65
49
  if schema_only and append:
@@ -72,6 +56,16 @@ def bc2pg( # noqa: C901
72
56
  if table:
73
57
  table_name = table.lower()
74
58
 
59
+ # take note if geometry type is specified as option
60
+ geometry_type_opt = geometry_type
61
+
62
+ # do not promote to multi if singlepart specified,
63
+ # otherwise default to always promoting to multipart in case mixed types are returned
64
+ if geometry_type_opt and geometry_type_opt.upper() in ["POINT", "LINE", "POLYGON"]:
65
+ promote_to_multi = False
66
+ else:
67
+ promote_to_multi = True
68
+
75
69
  # connect to target db
76
70
  db = Database(db_url)
77
71
 
@@ -82,6 +76,8 @@ def bc2pg( # noqa: C901
82
76
  urls = bcdata.define_requests(
83
77
  dataset,
84
78
  query=query,
79
+ bounds=bounds,
80
+ bounds_crs=bounds_crs,
85
81
  count=count,
86
82
  sortby=sortby,
87
83
  crs="epsg:3005",
@@ -101,19 +97,13 @@ def bc2pg( # noqa: C901
101
97
  table_definition = bcdata.get_table_definition(dataset)
102
98
 
103
99
  if not table_definition["schema"]:
104
- raise ValueError(
105
- "Cannot create table, schema details not found via bcdc api"
106
- )
100
+ raise ValueError("Cannot create table, schema details not found via bcdc api")
107
101
 
108
102
  # if geometry type is not provided, determine type by making the first request
109
103
  if not geometry_type:
110
- df = WFS.make_requests(
111
- [urls[0]], as_gdf=True, crs="epsg:3005", lowercase=True
112
- )
104
+ df = WFS.make_requests(dataset=dataset, urls=[urls[0]], as_gdf=True, crs="epsg:3005", lowercase=True)
113
105
  geometry_type = df.geom_type.unique()[0] # keep only the first type
114
- if numpy.any(
115
- df.has_z.unique()[0]
116
- ): # geopandas does not include Z in geom_type string
106
+ if numpy.any(df.has_z.unique()[0]): # geopandas does not include Z in geom_type string
117
107
  geometry_type = geometry_type + "Z"
118
108
 
119
109
  # if geometry type is still not populated try the last request
@@ -121,15 +111,14 @@ def bc2pg( # noqa: C901
121
111
  if not geometry_type:
122
112
  if not urls[-1] == urls[0]:
123
113
  df_temp = WFS.make_requests(
124
- [urls[-1]],
114
+ dataset=dataset,
115
+ urls=[urls[-1]],
125
116
  as_gdf=True,
126
117
  crs="epsg:3005",
127
118
  lowercase=True,
128
119
  silent=True,
129
120
  )
130
- geometry_type = df_temp.geom_type.unique()[
131
- 0
132
- ] # keep only the first type
121
+ geometry_type = df_temp.geom_type.unique()[0] # keep only the first type
133
122
  if numpy.any(
134
123
  df_temp.has_z.unique()[0]
135
124
  ): # geopandas does not include Z in geom_type string
@@ -143,9 +132,8 @@ def bc2pg( # noqa: C901
143
132
  raise ValueError("Geometry type {geometry_type} is not supported")
144
133
 
145
134
  # if primary key is not supplied, use default (if present in list)
146
- primary_keys = get_primary_keys()
147
- if not primary_key and dataset.lower() in primary_keys:
148
- primary_key = primary_keys[dataset.lower()]
135
+ if not primary_key and dataset.lower() in bcdata.primary_keys:
136
+ primary_key = bcdata.primary_keys[dataset.lower()]
149
137
 
150
138
  # fail if specified primary key is not in the table
151
139
  if primary_key and primary_key.upper() not in [
@@ -161,6 +149,7 @@ def bc2pg( # noqa: C901
161
149
  table_name,
162
150
  table_definition["schema"],
163
151
  geometry_type,
152
+ promote_to_multi,
164
153
  table_definition["comments"],
165
154
  primary_key,
166
155
  )
@@ -168,9 +157,7 @@ def bc2pg( # noqa: C901
168
157
 
169
158
  # check if column provided in sortby option is present in dataset
170
159
  if sortby and sortby.lower() not in column_names:
171
- raise ValueError(
172
- f"Specified sortby column {sortby} is not present in {dataset}"
173
- )
160
+ raise ValueError(f"Specified sortby column {sortby} is not present in {dataset}")
174
161
 
175
162
  # load the data
176
163
  if not schema_only:
@@ -178,9 +165,7 @@ def bc2pg( # noqa: C901
178
165
  for n, url in enumerate(urls):
179
166
  # if first url not downloaded above when checking geom type, do now
180
167
  if df is None:
181
- df = WFS.make_requests(
182
- [url], as_gdf=True, crs="epsg:3005", lowercase=True
183
- )
168
+ df = WFS.make_requests(dataset=dataset, urls=[url], as_gdf=True, crs="epsg:3005", lowercase=True)
184
169
  # tidy the resulting dataframe
185
170
  df = df.rename_geometry("geom")
186
171
  # lowercasify
@@ -193,23 +178,20 @@ def bc2pg( # noqa: C901
193
178
  df_nulls = df_nulls.drop(columns=["geom"])
194
179
  # remove rows with null geometry from geodataframe
195
180
  df = df[df["geom"].notna()]
196
- # cast to everything multipart because responses can have mixed types
197
- # geopandas does not have a built in function:
198
- # https://gis.stackexchange.com/questions/311320/casting-geometry-to-multi-using-geopandas
199
- df["geom"] = [
200
- MultiPoint([feature]) if isinstance(feature, Point) else feature
201
- for feature in df["geom"]
202
- ]
203
- df["geom"] = [
204
- MultiLineString([feature])
205
- if isinstance(feature, LineString)
206
- else feature
207
- for feature in df["geom"]
208
- ]
209
- df["geom"] = [
210
- MultiPolygon([feature]) if isinstance(feature, Polygon) else feature
211
- for feature in df["geom"]
212
- ]
181
+ # promote to multipart
182
+ if promote_to_multi:
183
+ df["geom"] = [
184
+ MultiPoint([feature]) if isinstance(feature, Point) else feature
185
+ for feature in df["geom"]
186
+ ]
187
+ df["geom"] = [
188
+ MultiLineString([feature]) if isinstance(feature, LineString) else feature
189
+ for feature in df["geom"]
190
+ ]
191
+ df["geom"] = [
192
+ MultiPolygon([feature]) if isinstance(feature, Polygon) else feature
193
+ for feature in df["geom"]
194
+ ]
213
195
 
214
196
  # run the load in two parts, one with geoms, one with no geoms
215
197
  log.info(f"Writing {dataset} to database as {schema_name}.{table_name}")
@@ -224,22 +206,8 @@ def bc2pg( # noqa: C901
224
206
  df = None
225
207
 
226
208
  # once load complete, note date/time of load completion in bcdata.log
227
- if timestamp:
228
- log.info("Logging download date to bcdata.log")
229
- db.execute(
230
- """CREATE SCHEMA IF NOT EXISTS bcdata;
231
- CREATE TABLE IF NOT EXISTS bcdata.log (
232
- table_name text PRIMARY KEY,
233
- latest_download timestamp WITH TIME ZONE
234
- );
235
- """
236
- )
237
- db.execute(
238
- """INSERT INTO bcdata.log (table_name, latest_download)
239
- SELECT %s as table_name, NOW() as latest_download
240
- ON CONFLICT (table_name) DO UPDATE SET latest_download = NOW();
241
- """,
242
- (schema_name + "." + table_name,),
243
- )
209
+ # do not log refreshes here, they called by cli once loaded to target table
210
+ if timestamp and not refresh:
211
+ db.log(schema_name, table_name)
244
212
 
245
213
  return schema_name + "." + table_name