Skip to content

Commit

Permalink
element: missing geometric information is downloaded when needed
Browse files Browse the repository at this point in the history
  • Loading branch information
franz-benjamin committed Mar 14, 2022
1 parent a48bca8 commit d1c0a4e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
42 changes: 25 additions & 17 deletions OSMPythonTools/element.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from bs4 import BeautifulSoup
import copy
import dateutil.parser
import geojson
Expand Down Expand Up @@ -124,10 +125,10 @@ def history(self):
return history

### members
def __members(self):
return self.__getElement('members') if self._json is not None else self._soup.find_all('member')
def members(self, shallow=True):
members = self.__members()
def __members(self, onlyInner=False, onlyOuter=False):
return [m for m in (self.__getElement('members') if self._json is not None else self._soup.find_all('member')) if (not onlyInner or m['role'] == 'inner') and (not onlyOuter or m['role'] == 'outer')]
def members(self, shallow=True, onlyInner=False, onlyOuter=False):
members = self.__members(onlyInner=onlyInner, onlyOuter=onlyOuter)
if members is None or len(members) == 0:
return []
api = SingletonApi()
Expand Down Expand Up @@ -155,25 +156,34 @@ def tag(self, key):

### geometry
def geometry(self):
return self.__geometry(self)
def __geometry(self, asList=False):
try:
if self.type() == 'node':
if not self.lon() or not self.lat():
self._raiseException('Cannot build geometry: geometry information not included.')
return geojson.Point((self.lon(), self.lat()))
return [(self.lon(), self.lat())] if asList else geojson.Point((self.lon(), self.lat()))
elif self.type() == 'way':
if not self.__getElement('geometry'):
self._raiseException('Cannot build geometry: geometry information not included.')
cs = self.__geometry_csToList(self.__getElement('geometry'))
if self.__getElement('geometry'):
cs = self.__geometry_csToList(self.__getElement('geometry'))
else:
api = OSMPythonTools.api.Api()
d = api.query(self.type() + '/' + str(self.id()) + '/full')
dSoup = BeautifulSoup(d._xml, 'xml')
nodeIds = [n['ref'] for n in dSoup.find(self.type(), id=str(self.id())).children if n.name == 'nd']
cs = [dSoup.osm.find('node', id=nId) for nId in nodeIds]
cs = [{'lat': float(c['lat']), 'lon': float(c['lon'])} for c in cs]
if asList:
return cs
if self.__geometry_equal(cs[0], cs[-1]):
return geojson.Polygon([cs])
else:
return geojson.LineString(cs)
elif self.type() == 'relation':
members = copy.deepcopy(self.__members())
membersOuter = self.__geometry_extract(members, 'outer')
membersOuter = self.__geometry_extract(self.members(onlyOuter=True))
if len(membersOuter) == 0:
self._raiseException('Cannot build geometry: no outer rings found.')
membersInner = self.__geometry_extract(members, 'inner')
membersInner = self.__geometry_extract(self.members(onlyInner=True))
ringsOuter = self.__geometry_buildRings(membersOuter)
ringsInner = self.__geometry_buildRings(membersInner)
ringsOuter = self.__geometry_orientRings(ringsOuter, positive=True)
Expand Down Expand Up @@ -219,14 +229,12 @@ def __geometry_orientRings(self, rings, positive=True):
return [list(reversed(r)) if positive ^ self.__geometry_polygonPositiveOriented(r) else r for r in rings]
def __geometry_csToList(self, cs):
return [(c['lon'], c['lat']) for c in cs]
def __geometry_extract(self, members, role):
def __geometry_extract(self, members):
extracted = []
for m in members:
if m['role'] == role:
if 'geometry' in m:
extracted.append(self.__geometry_csToList(m['geometry']))
else:
self._raiseException('Cannot build geometry: relation in relation not supported.')
if m.type() == 'relation':
self._raiseException('Cannot build geometry: relation in relation not supported.')
extracted.append(self.__geometry_csToList(m.__geometry(asList=True)))
return extracted
def __geometry_buildRings(self, members):
rings = []
Expand Down
4 changes: 4 additions & 0 deletions version-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

Please note that versions may include breaking changes.

## Version v0.3.5

* [improvement] missing geometric information is downloaded when needed

## Version v0.3.4

* [bug] areaId was only computed for the first element of a `NominatimResult`, but not for the first element for which it does not vanish
Expand Down

0 comments on commit d1c0a4e

Please sign in to comment.