Skip to content

ContinuousAugmentedDiff#

Iterator for continuous monitoring of OpenStreetMap changes using augmented diffs.

Builds on AugmentedDiff to provide automatic polling with backoff.

Features#

  • Continuous monitoring
  • Automatic sequence number tracking
  • Exponential backoff during errors
  • Configurable polling intervals
  • Bounding box filtering

Basic Usage#

from osmdiff import ContinuousAugmentedDiff

# Monitor London area
monitor = ContinuousAugmentedDiff(
    minlon=-0.489,
    minlat=51.28,
    maxlon=0.236,
    maxlat=51.686
)

for changes in monitor:  # Runs indefinitely
    print(f"Changeset {changes.sequence_number}:")
    print(f"  New: {len(changes.create)}")
    print(f"  Modified: {len(changes.modify)}")

Advanced Configuration#

monitor = ContinuousAugmentedDiff(
    minlon=-0.489,
    minlat=51.28,
    maxlon=0.236,
    maxlat=51.686,
    min_interval=60,  # Minimum 1 minute between checks
    max_interval=300  # Maximum 5 minutes during backoff
)

API Reference#

Iterator for continuously fetching augmented diffs with backoff.

Yields AugmentedDiff objects as new diffs become available.

Parameters:

Name Type Description Default
minlon Optional[float]

Minimum longitude of bounding box

None
minlat Optional[float]

Minimum latitude of bounding box

None
maxlon Optional[float]

Maximum longitude of bounding box

None
maxlat Optional[float]

Maximum latitude of bounding box

None
base_url Optional[str]

Override default Overpass API URL

None
timeout Optional[int]

Request timeout in seconds

None
min_interval int

Minimum seconds between checks (default: 30)

30
max_interval int

Maximum seconds between checks (default: 120)

120
Source code in src/osmdiff/augmenteddiff.py
def __init__(
    self,
    minlon: Optional[float] = None,
    minlat: Optional[float] = None,
    maxlon: Optional[float] = None,
    maxlat: Optional[float] = None,
    base_url: Optional[str] = None,
    timeout: Optional[int] = None,
    min_interval: int = 30,
    max_interval: int = 120,
):
    self.bbox = (minlon, minlat, maxlon, maxlat)
    self.base_url = base_url
    self.timeout = timeout
    self.min_interval = min_interval
    self.max_interval = max_interval

    self._current_sequence = None
    self._current_interval = min_interval
    self._last_check = None
    self._logger = logging.getLogger(__name__)

__iter__() #

Source code in src/osmdiff/augmenteddiff.py
def __iter__(self):
    return self

__next__() #

Source code in src/osmdiff/augmenteddiff.py
def __next__(self) -> AugmentedDiff:
    while True:
        self._wait_for_next_check()

        # check if we have a newer sequence on the remote
        newest_remote = AugmentedDiff.get_state(timeout=self.timeout)

        # if we don't have a local sequence number yet, set it
        if self._current_sequence is None:
            self._current_sequence = newest_remote

        # if we do, proceed ony if the remote is newer
        elif self._current_sequence >= newest_remote:
            continue

        # Create diff object for new sequence
        diff = AugmentedDiff(
            minlon=self.bbox[0],
            minlat=self.bbox[1],
            maxlon=self.bbox[2],
            maxlat=self.bbox[3],
            sequence_number=self._current_sequence,
            base_url=self.base_url,
            timeout=self.timeout,
        )

        # Try to retrieve the diff
        try:
            status = diff.retrieve(auto_increment=False)
            if status != 200:
                self._logger.warning(f"Failed to retrieve diff: HTTP {status}")
                self._backoff()
                continue

            # Success! Reset backoff and update sequence
            self._reset_backoff()
            self._current_sequence += 1
            return diff

        except Exception as e:
            self._logger.warning(f"Error retrieving diff: {e}")
            self._backoff()
            continue

See Also#