Skip to content

Commit 5b2ed9a

Browse files
Merge pull request #342 from johntruckenbrodt/feature/s1_geogrid
[SAFE.geo_grid] new method
2 parents e41438c + f203885 commit 5b2ed9a

File tree

5 files changed

+84
-6
lines changed

5 files changed

+84
-6
lines changed

environment-dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ dependencies:
66
- python>=3.8
77
- progressbar2
88
- numpy<2.0
9-
- spatialist>=0.12.1
9+
- spatialist>=0.15.0
1010
- pyyaml
1111
- requests
1212
- psycopg2

environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ dependencies:
66
- python>=3.8
77
- progressbar2
88
- numpy<2.0
9-
- spatialist>=0.12.1
9+
- spatialist>=0.15.0
1010
- pyyaml
1111
- requests
1212
- psycopg2

pyroSAR/drivers.py

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
import tarfile as tf
3939
import xml.etree.ElementTree as ET
4040
import zipfile as zf
41-
from datetime import datetime
41+
from datetime import datetime, timezone
42+
from dateutil.parser import parse as dateparse
4243
from time import strptime, strftime
4344
from statistics import median
4445
from itertools import groupby
@@ -56,7 +57,7 @@
5657
from spatialist import crsConvert, sqlite3, Vector, bbox
5758
from spatialist.ancillary import parse_literal, finder, multicore
5859

59-
from sqlalchemy import create_engine, Table, MetaData, Column, Integer, String, exc, insert
60+
from sqlalchemy import create_engine, Table, MetaData, Column, Integer, String, exc
6061
from sqlalchemy import inspect as sql_inspect
6162
from sqlalchemy.event import listen
6263
from sqlalchemy.orm import sessionmaker
@@ -68,7 +69,6 @@
6869
import socket
6970
import time
7071
import platform
71-
import subprocess
7272
import logging
7373

7474
log = logging.getLogger(__name__)
@@ -1710,6 +1710,75 @@ def removeGRDBorderNoise(self, method='pyroSAR'):
17101710
"""
17111711
S1.removeGRDBorderNoise(self, method=method)
17121712

1713+
def geo_grid(self, outname=None, driver=None, overwrite=True):
1714+
"""
1715+
get the geo grid as vector geometry
1716+
1717+
Parameters
1718+
----------
1719+
outname: str
1720+
the name of the vector file to be written
1721+
driver: str
1722+
the output file format; needs to be defined if the format cannot
1723+
be auto-detected from the filename extension
1724+
overwrite: bool
1725+
overwrite an existing vector file?
1726+
1727+
Returns
1728+
-------
1729+
~spatialist.vector.Vector or None
1730+
the vector object if `outname` is None, None otherwise
1731+
1732+
See also
1733+
--------
1734+
spatialist.vector.Vector.write
1735+
"""
1736+
annotations = self.findfiles(self.pattern_ds)
1737+
key = lambda x: re.search('-[vh]{2}-', x).group()
1738+
groups = groupby(sorted(annotations, key=key), key=key)
1739+
annotations = [list(value) for key, value in groups][0]
1740+
1741+
vec = Vector(driver='Memory')
1742+
vec.addlayer('geogrid', 4326, ogr.wkbPoint25D)
1743+
field_defs = [
1744+
("swath", ogr.OFTString),
1745+
("azimuthTime", ogr.OFTDateTime),
1746+
("slantRangeTime", ogr.OFTReal),
1747+
("line", ogr.OFTInteger),
1748+
("pixel", ogr.OFTInteger),
1749+
("incidenceAngle", ogr.OFTReal),
1750+
("elevationAngle", ogr.OFTReal),
1751+
]
1752+
for name, ftype in field_defs:
1753+
field = ogr.FieldDefn(name, ftype)
1754+
vec.layer.CreateField(field)
1755+
1756+
for ann in annotations:
1757+
with self.getFileObj(ann) as ann_xml:
1758+
tree = ET.fromstring(ann_xml.read())
1759+
swath = tree.find(".//adsHeader/swath").text
1760+
points = tree.findall(".//geolocationGridPoint")
1761+
for point in points:
1762+
meta = {child.tag: child.text for child in point}
1763+
meta["swath"] = swath
1764+
x = float(meta.pop("longitude"))
1765+
y = float(meta.pop("latitude"))
1766+
z = float(meta.pop("height"))
1767+
geom = ogr.Geometry(ogr.wkbPoint25D)
1768+
geom.AddPoint(x, y, z)
1769+
az_time = dateparse(meta["azimuthTime"])
1770+
meta["azimuthTime"] = az_time.replace(tzinfo=timezone.utc)
1771+
for key in ["slantRangeTime", "incidenceAngle", "elevationAngle"]:
1772+
meta[key] = float(meta[key])
1773+
for key in ["line", "pixel"]:
1774+
meta[key] = int(meta[key])
1775+
vec.addfeature(geom, fields=meta)
1776+
geom = None
1777+
if outname is None:
1778+
return vec
1779+
else:
1780+
vec.write(outfile=outname, driver=driver, overwrite=overwrite)
1781+
17131782
def getOSV(self, osvdir=None, osvType='POE', returnMatch=False, useLocal=True, timeout=300, url_option=1):
17141783
"""
17151784
download Orbit State Vector files for the scene

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
progressbar2
22
numpy<2.0
3-
spatialist>=0.12.1
3+
spatialist>=0.15.0
44
pyyaml
55
requests
66
psycopg2

tests/test_drivers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,12 @@ def test_geometry(testdata, dataset):
301301
scene = pyroSAR.identify(testdata[dataset])
302302
with scene.geometry() as geom:
303303
assert isinstance(geom, Vector)
304+
305+
306+
def test_geo_grid(tmpdir, testdata):
307+
scene = pyroSAR.identify(testdata['s1'])
308+
with scene.geo_grid() as geom:
309+
assert isinstance(geom, Vector)
310+
out = tmpdir / "geogrid.gpkg"
311+
scene.geo_grid(outname=str(out))
312+
assert out.exists()

0 commit comments

Comments
 (0)