Coverage for sarvey/osm_utils.py: 0%
55 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-17 12:36 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-17 12:36 +0000
1#!/usr/bin/env python
3# SARvey - A multitemporal InSAR time series tool for the derivation of displacements.
4#
5# Copyright (C) 2021-2024 Andreas Piter (IPI Hannover, piter@ipi.uni-hannover.de)
6#
7# This software was developed together with FERN.Lab (fernlab@gfz-potsdam.de) in the context
8# of the SAR4Infra project with funds of the German Federal Ministry for Digital and
9# Transport and contributions from Landesamt fuer Vermessung und Geoinformation
10# Schleswig-Holstein and Landesbetrieb Strassenbau und Verkehr Schleswig-Holstein.
11#
12# This program is free software: you can redistribute it and/or modify it under
13# the terms of the GNU General Public License as published by the Free Software
14# Foundation, either version 3 of the License, or (at your option) any later
15# version.
16#
17# Important: This package uses PyMaxFlow. The core of PyMaxflows library is the C++
18# implementation by Vladimir Kolmogorov. It is also licensed under the GPL, but it REQUIRES that you
19# cite [BOYKOV04] (see LICENSE) in any resulting publication if you use this code for research purposes.
20# This requirement extends to SARvey.
21#
22# This program is distributed in the hope that it will be useful, but WITHOUT
23# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
24# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
25# details.
26#
27# You should have received a copy of the GNU Lesser General Public License along
28# with this program. If not, see <https://www.gnu.org/licenses/>.
30"""Osm utils module for SARvey."""
31import numpy as np
32import overpy
33from logging import Logger
34from shapely import Point
36from mintpy.utils import readfile, utils as ut
39def getSpatialExtend(*, geom_file: str, logger: Logger):
40 """Get spatial extend of the radar image.
42 Parameters
43 ----------
44 geom_file: str
45 path of geometryRadar.h5 file
46 logger: Logger
47 Logging handler.
49 Returns
50 -------
51 ll_corner_wgs: list
52 list of coordinates of the lower-left corner of the radar image in WGS84 coordinates.
53 ur_corner_wgs: list
54 list of coordinates of the upper-right corner of the radar image in WGS84 coordinates.
55 coord: np.ndarray
56 coordinates of all pixels in the radar image in WGS84.
57 atr: dict
58 metadata dictionary from geometryRadar.h5.
59 """
60 logger.info(msg='read spatial extend from geometryRadar.h5')
61 _, atr = readfile.read(geom_file)
62 coord = ut.coordinate(atr, lookup_file=geom_file)
63 lat, atr = readfile.read(geom_file, datasetName='latitude')
64 lon, _ = readfile.read(geom_file, datasetName='longitude')
66 # radar image is flipped up-down
67 # unclear: check if bounding box fits. Otherwise, change to max and min values of lat and lon
68 ll_bbox = [np.nanmin(lat), np.nanmin(lon)]
69 ur_bbox = [np.nanmax(lat), np.nanmax(lon)]
71 img_ext = [
72 Point(lon[0, 0], lat[0, 0]),
73 Point(lon[-1, 0], lat[-1, 0]),
74 Point(lon[-1, -1], lat[-1, -1]),
75 Point(lon[0, -1], lat[0, -1])
76 ]
77 return ll_bbox, ur_bbox, img_ext, coord, atr
80def runOsmQuery(*, ll_corner_wgs: np.ndarray, ur_corner_wgs: np.ndarray, type_list: list,
81 logger: Logger) -> overpy.Result:
82 """Query OSM database for transport infrastructure within the spatial extent of the radar image.
84 Parameters
85 ----------
86 ll_corner_wgs: np.ndarray
87 coordinates of the lower-left corner of the radar image in WGS84 coordinates.
88 ur_corner_wgs: np.ndarray
89 coordinates of the upper-right corner of the radar image in WGS84 coordinates.
90 type_list: list
91 List of street types that shall be queried at the OSM database.
92 logger: Logger
93 Logging handler.
95 Returns
96 -------
97 result: overpy.Result
98 results of the overpy query to OSM database.
99 """
100 # Initialize overpass connection
101 api = overpy.Overpass()
103 # Request data from API
104 logger.info(msg='querying OSM database for infra types...')
105 # query_cmd = "way({},{},{},{}) [""highway=motorway_link""]; (._;>;); out body;"
107 query_cmd = "[bbox: {},{},{},{}];("
108 for infra_type in type_list:
109 logger.info(msg='\t - {}'.format(infra_type))
110 if infra_type == 'rail':
111 query_cmd += "way[railway={}];".format(infra_type)
112 else:
113 query_cmd += "way[highway={}];".format(infra_type)
115 query_cmd += ");(._; >;); out body;" # skel
117 cmd = query_cmd.format(ll_corner_wgs[0], ll_corner_wgs[1],
118 ur_corner_wgs[0], ur_corner_wgs[1])
119 logger.info(msg="\n" + cmd + "\n")
120 result = api.query(cmd)
122 if len(result.ways) == 0:
123 logger.error(msg='Empty OSM query results. No roads or railway tracks found.')
124 raise ValueError
126 logger.info(msg='...done.')
127 return result
130def runOsmQueryBridge(*, ll_corner_wgs: np.ndarray, ur_corner_wgs: np.ndarray, bridge_highway: bool,
131 bridge_railway: bool, logger: Logger) -> overpy.Result:
132 """Query OSM database for bridges of transport infrastructure within the spatial extent of the radar image.
134 Parameters
135 ----------
136 ll_corner_wgs: np.ndarray
137 coordinates of the lower-left corner of the radar image in WGS84 coordinates.
138 ur_corner_wgs: np.ndarray
139 coordinates of the upper-right corner of the radar image in WGS84 coordinates.
140 bridge_highway: bool
141 Set true to query highway bridges.
142 bridge_railway: bool
143 Set true to query railway bridges.
144 logger: Logger
145 Logging handler.
147 Returns
148 -------
149 result: overpy.Result
150 results of the overpy query to OSM database.
151 """
152 # Initialize overpass connection
153 api = overpy.Overpass()
155 # Request data from API
156 logger.info(msg='querying OSM database for infra types...')
157 # query_cmd = "way({},{},{},{}) [""highway=motorway_link""]; (._;>;); out body;"
159 query_cmd = "[bbox: {},{},{},{}];("
161 if bridge_highway:
162 logger.info(msg='\t - bridge_highway')
163 query_cmd += 'way[highway~"^(motorway|motorway_link|trunk|trunk_link)$"][bridge];'
165 if bridge_railway:
166 logger.info(msg='\t - bridge_railway')
167 query_cmd += 'way[railway=rail][bridge];'
169 if (bridge_highway is False) & (bridge_railway is False):
170 logger.info(msg='\t - all bridges')
171 query_cmd += 'way[bridge];'
173 query_cmd += ");(._; >;); out body;" # skel
175 cmd = query_cmd.format(ll_corner_wgs[0], ll_corner_wgs[1],
176 ur_corner_wgs[0], ur_corner_wgs[1])
177 logger.info(msg="\n" + cmd + "\n")
178 result = api.query(cmd)
180 if len(result.ways) == 0:
181 logger.error(msg='Empty OSM query results. No bridges found.')
182 raise ValueError
184 logger.info(msg='...done.')
185 return result