Skip to content

Commit c1978e3

Browse files
committed
simplify geospatial property management
1 parent 0827d16 commit c1978e3

File tree

5 files changed

+46
-61
lines changed

5 files changed

+46
-61
lines changed

Makefile

+2-3
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ help:
5151
@echo
5252
@echo "make targets:"
5353
@echo
54-
@echo " createdb: create PostgreSQL/PostGIS database"
55-
@echo " dropdb: drop PostgreSQL/PostGIS database"
54+
@echo " createdb: create PostgreSQL database"
55+
@echo " dropdb: drop PostgreSQL database"
5656
@echo " setup: create models and search index"
5757
@echo " setup_data: download core metadata
5858
@echo " teardown: delete models and search index"
@@ -81,7 +81,6 @@ coverage:
8181

8282
createdb:
8383
createdb $(PG_FLAGS) -E UTF8
84-
psql $(PG_FLAGS) -c "create extension postgis;"
8584

8685
dropdb:
8786
dropdb $(PG_FLAGS)

debian/control

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Vcs-Git: https://github.com/woudc/woudc-data-registry.git
99

1010
Package: woudc-data-registry
1111
Architecture: all
12-
Depends: elasticsearch (>=5.5.0), postgis, postgresql, python3-click, python-elasticsearch, python-geoalchemy2, python3-psycopg2, python3-requests, python3-six, python3-sqlalchemy
12+
Depends: elasticsearch (>=5.5.0), postgresql, python3-click, python-elasticsearch, python3-psycopg2, python3-requests, python3-six, python3-sqlalchemy
1313
Homepage: https://woudc.org
1414
Description: WOUDC Data Registry is a platform that manages Ozone and
1515
Ultraviolet Radiation data in support of the World Ozone and Ultraviolet

requirements.txt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
click
22
elasticsearch
3-
geoalchemy2
43
psycopg2
54
requests
65
six

woudc_data_registry/models.py

+43-45
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,16 @@
4848

4949
import click
5050
import csv
51-
# from geoalchemy2.shape import to_shape
52-
from geoalchemy2.types import Geometry
5351
import json
54-
from sqlalchemy import (Boolean, Column, create_engine, Date, DateTime,
52+
from sqlalchemy import (Boolean, Column, create_engine, Date, DateTime, Float,
5553
Enum, ForeignKey, Integer, String, Time, UnicodeText,
5654
UniqueConstraint)
5755
from sqlalchemy.exc import OperationalError, ProgrammingError
5856
from sqlalchemy.ext.declarative import declarative_base
5957
from sqlalchemy.orm import relationship
6058

61-
from woudc_data_registry import registry, util
59+
from woudc_data_registry import registry
60+
from woudc_data_registry.util import point2geojsongeometry
6261

6362
base = declarative_base()
6463

@@ -139,7 +138,8 @@ class Contributor(base):
139138

140139
last_validated_datetime = Column(DateTime, nullable=False,
141140
default=datetime.utcnow())
142-
location = Column(Geometry('POINT', srid=4326), nullable=False)
141+
x = Column(Float, nullable=False)
142+
y = Column(Float, nullable=False)
143143

144144
# relationships
145145
country = relationship('Country', backref=__tablename__)
@@ -154,14 +154,15 @@ def __init__(self, dict_):
154154
self.url = dict_['url']
155155
self.email = dict_['email']
156156
self.ftp_username = dict_['ftp_username']
157-
self.location = util.point2ewkt(dict_['x'], dict_['y'])
157+
self.x = dict_['x']
158+
self.y = dict_['y']
158159

159160
@property
160161
def __geo_interface__(self):
161162
return {
162163
'id': self.identifier,
163164
'type': 'Feature',
164-
# 'geometry': to_shape(self.location).__geo_interface__,
165+
'geometry': point2geojsongeometry(self.x, self.y),
165166
'properties': {
166167
'name': self.name,
167168
'country_id': self.country_id,
@@ -222,8 +223,9 @@ class Station(base):
222223
last_validated_datetime = Column(DateTime, nullable=False,
223224
default=datetime.utcnow())
224225

225-
# location = Column(Geometry('POINT', srid=4326), nullable=False)
226-
location = Column(Geometry(srid=0), nullable=False)
226+
x = Column(Float, nullable=False)
227+
y = Column(Float, nullable=False)
228+
z = Column(Float, nullable=True)
227229

228230
# relationships
229231
country = relationship('Country', backref=__tablename__)
@@ -240,8 +242,32 @@ def __init__(self, dict_):
240242
self.contributor_id = dict_['contributor_id']
241243
self.wmo_region = dict_['wmo_region']
242244
self.active_start_date = dict_['active_start_date']
243-
self.active_end_datet = dict_['active_end_date']
244-
self.location = util.point2ewkt(dict_['x'], dict_['y'], dict_['z'])
245+
self.active_end_date = dict_['active_end_date']
246+
self.x = dict_['x']
247+
self.y = dict_['y']
248+
self.z = dict_['z']
249+
250+
def __geo_interface__(self):
251+
coordinates = [self.x, self.y]
252+
253+
if self.z is not None:
254+
coordinates.append(self.z)
255+
256+
return {
257+
'id': self.identifier,
258+
'type': 'Feature',
259+
'geometry': point2geojsongeometry(self.x, self.y, self.z),
260+
'properties': {
261+
'name': self.name,
262+
'stn_type': self.stn_type,
263+
'gaw_id': self.gaw_id,
264+
'country': self.country.country_name,
265+
# TODO: allow for contributor 1..n
266+
'wmo_region': self.wmo_region,
267+
'active_start_date': self.active_start_date,
268+
'active_end_date': self.active_end_date
269+
}
270+
}
245271

246272
def __repr__(self):
247273
return 'Station ({}, {})'.format(self.identifier, self.name)
@@ -276,8 +302,9 @@ class DataRecord(base):
276302
instrument_model = Column(String, nullable=False)
277303
instrument_number = Column(String, nullable=False)
278304

279-
location = Column(Geometry(geometry_type='POINT', srid=4326),
280-
nullable=False)
305+
x = Column(Float, nullable=False)
306+
y = Column(Float, nullable=False)
307+
z = Column(Float, nullable=True)
281308

282309
timestamp_utcoffset = Column(String, nullable=False)
283310
timestamp_date = Column(Date, nullable=False)
@@ -341,9 +368,9 @@ def __init__(self, ecsv):
341368
if 'Time' in ecsv.extcsv['TIMESTAMP']:
342369
self.timestamp_time = ecsv.extcsv['TIMESTAMP']['Time']
343370

344-
self.location = util.point2ewkt(ecsv.extcsv['LOCATION']['Longitude'],
345-
ecsv.extcsv['LOCATION']['Latitude'],
346-
ecsv.extcsv['LOCATION']['Height'])
371+
self.x = csv.extcsv['LOCATION']['Longitude']
372+
self.y = csv.extcsv['LOCATION']['Latitude']
373+
self.z = csv.extcsv['LOCATION']['Height']
347374

348375
self.extcsv = ecsv.extcsv
349376
self.raw = ecsv._raw
@@ -387,35 +414,6 @@ def get_waf_path(self, basepath):
387414

388415
return '/'.join(url_tokens)
389416

390-
def to_geojson_dict(self):
391-
"""return dict as a GeoJSON representation"""
392-
393-
data = self.__dict__
394-
395-
fields_to_remove = [
396-
'_sa_instance_state',
397-
'extcsv',
398-
'location',
399-
'ingest_filepath',
400-
]
401-
402-
geometry = util.point2geojsongeometry(
403-
data['extcsv']['LOCATION']['Longitude'],
404-
data['extcsv']['LOCATION']['Latitude'],
405-
data['extcsv']['LOCATION']['Height'])
406-
407-
LOGGER.debug('removing internal / unwanted fields')
408-
for field_to_remove in fields_to_remove:
409-
data.pop(field_to_remove, None)
410-
411-
feature = {
412-
'type': 'Feature',
413-
'geometry': geometry,
414-
'properties': data
415-
}
416-
417-
return feature
418-
419417
def __repr__(self):
420418
return 'DataRecord({}, {})'.format(self.identifier, self.url)
421419

woudc_data_registry/util.py

-11
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,6 @@
5050
LOGGER = logging.getLogger(__name__)
5151

5252

53-
def point2ewkt(x, y, z=None, srid=4326):
54-
"""helper function to generate EWKT of point"""
55-
56-
if z is None or int(z) == 0:
57-
point = 'SRID={};POINT({} {})'.format(srid, x, y)
58-
else:
59-
point = 'SRID={};POINTZ({} {} {})'.format(srid, x, y, z)
60-
61-
return point
62-
63-
6453
def point2geojsongeometry(x, y, z=None):
6554
"""helper function to generate GeoJSON geometry of point"""
6655

0 commit comments

Comments
 (0)