Skip to content

Instantly share code, notes, and snippets.

@nimmneun
Created July 7, 2016 06:38
Show Gist options
  • Save nimmneun/c5c123848a335e2c6915689058d72ed7 to your computer and use it in GitHub Desktop.
Save nimmneun/c5c123848a335e2c6915689058d72ed7 to your computer and use it in GitHub Desktop.
openstreetmap node, way, relation extractor
<?php
class OsmMapParser
{
const TYPE_NODE = 'node';
const TYPE_WAY = 'way';
const TYPE_RELATION = 'relation';
private $source;
private $target;
private $current;
private $isOpen = false;
private $hasQuery = false;
private $count;
/**
* OsmMapParser constructor.
* @param string $path
*/
public function __construct($path)
{
$this->source = new SplFileObject($path, 'r');
$this->target = new SplFileObject(str_replace('.osm', '.xml', $path), 'wb+');
}
/**
* @param string $query
*/
public function findNodesWith($query = 'housenumber')
{
$this->target->fwrite('<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL . '<nodes>' . PHP_EOL);
while ($line = $this->source->fgets()) {
$this->findData(self::TYPE_NODE, trim($line), $query);
}
$this->target->fwrite('</nodes>');
echo PHP_EOL . $this->count . ' nodes gefunden' . PHP_EOL;
}
/**
* @param string $query
*/
public function findWaysWith($query = 'housenumber')
{
$this->target->fwrite('<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL . '<ways>' . PHP_EOL);
while ($line = $this->source->fgets()) {
$this->findData(self::TYPE_WAY, trim($line), $query);
}
$this->target->fwrite('</ways>');
echo PHP_EOL . $this->count . ' ways gefunden' . PHP_EOL;
}
/**
* @param string $query
*/
public function findRelationsWith($query = 'housenumber')
{
$this->target->fwrite('<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL . '<relations>' . PHP_EOL);
while ($line = $this->source->fgets()) {
$this->findData(self::TYPE_RELATION, trim($line), $query);
}
$this->target->fwrite('</relations>');
echo PHP_EOL . $this->count . ' relations gefunden' . PHP_EOL;
}
/**
* @param string $type
* @param string $line
* @param string $query
*/
private function findData($type, $line, $query)
{
if (0 === strpos($line, '<' . $type . ' ') && substr($line, -2) == '/>') {
// direkt weiter wenns ein self closing node tag ist
return;
} elseif (0 === strpos($line, '<' . $type . ' ')) {
// node open tag festhalten
$this->current .= ' ' . $line . PHP_EOL;
$this->isOpen = true;
} elseif ($this->isOpen && 0 === strpos($line, '</' . $type . '>')) {
// bei node close tag, node festhalten wenn query zuvor gefunden
if ($this->hasQuery) {
$this->target->fwrite($this->current . ' ' . $line . PHP_EOL);
$this->count++;
}
$this->reset();
} elseif ($this->isOpen) {
// alles nach node open und vor node close tag festhalten
$this->current .= ' ' . $line . PHP_EOL;
if (false !== strpos($line, $query)) {
$this->hasQuery = true;
}
}
}
/**
* Nach schießendem node tag alles wieder zurücksetzen.
*/
public function reset()
{
$this->isOpen = $this->hasQuery = false;
$this->current = null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment