http://www.phing.info/

Source Code Coverage

Designed for use with PHPUnit, Xdebug and Phing.

Methods: 6 LOC: 210 Statements: 95
Legend: executednot executeddead code
Source file Statements Methods Total coverage
Way.php 100.0% 33.3% 96.0%
   
1
<?php
2
/**
3
 * Way.php
4
 * 25-Apr-2011
5
 *
6
 * PHP Version 5
7
 *
8
 * @category Services
9
 * @package  Services_OpenStreetMap
10
 * @author   Ken Guest <kguest@php.net>
11
 * @license  BSD http://www.opensource.org/licenses/bsd-license.php
12
 * @version  Release: @package_version@
13
 * @link     Way.php
14
 */
15
16
/**
17
 * Services_OpenStreetMap_Way
18
 *
19
 * @category Services
20
 * @package  Services_OpenStreetMap
21
 * @author   Ken Guest <kguest@php.net>
22
 * @license  BSD http://www.opensource.org/licenses/bsd-license.php
23
 * @link     Way.php
24
 */
25
class Services_OpenStreetMap_Way extends Services_OpenStreetMap_Object
26 1
{
27
    protected $type = 'way';
28
    protected $nodes = array();
29
    protected $nodesNew = array();
30
    protected $dirtyNodes = false;
31
32
    /**
33
     * Return true if the way can be considered 'closed'.
34
     *
35
     * @return boolean
36
     */
37
    public function isClosed()
38
    {
39
        // Not closed if there's just one node.
40
        // Otherwise a way is considered closed if the first node has
41
        // the same id as the last.
42 4
        if (empty($this->nodes)) {
43 4
            $nodes = $this->getNodes();
44 4
        } else {
45
            $nodes = $this->nodes;
46
        }
47 4
        if (sizeof($nodes) == 1) {
48 1
            $closed = false;
49 1
        } else {
50 3
            $closed = ($nodes[0]) == ($nodes[count($nodes) - 1]);
51
        }
52 4
        return $closed;
53
    }
54
55
    /**
56
     * Return an array containing the IDs of all nodes in the way.
57
     *
58
     * @return array
59
     */
60
    public function getNodes()
61
    {
62 8
        if (empty($this->nodes)) {
63 8
            $obj = simplexml_load_string($this->xml);
64 8
            $nds = $obj->xpath('//nd');
65 8
            $nodes = array();
66 8
            foreach ($nds as $node) {
67 8
                $nodes[] = (string) $node->attributes()->ref;
68 8
            }
69 8
            $this->nodes = $nodes;
70 8
        }
71 8
        return $this->nodes;
72
    }
73
74
    /**
75
     * Add a node to the way.
76
     *
77
     * @param node $node An Services_OpenStreetMap_Node object.
78
     *
79
     * @return Services_OpenStreetMap_Way
80
     */
81
    public function addNode(Services_OpenStreetMap_Node $node)
82
    {
83 1
        $id = $node->getId();
84 1
        $pos = array_search($id, $this->nodes);
85 1
        if ($pos === false) {
86 1
            $this->action  = 'modify';
87 1
            $this->nodes[] = $id;
88 1
            $this->dirty   = true;
89 1
            $this->dirtyNodes = true;
90 1
            $this->nodesNew[] = $id;
91 1
        }
92 1
        return $this;
93
    }
94
95
    /**
96
     * Remove a node from the way.
97
     *
98
     * @param node $node Either a Node object or an id/ref of such an object.
99
     *
100
     * @return Services_OpenStreetMap_Way
101
     * @throws Services_OpenStreetMap_InvalidArgumentException
102
     */
103
    public function removeNode($node)
104
    {
105 2
        if (empty($this->nodes)) {
106 1
            $this->nodes = $this->getNodes();
107 1
        }
108 2
        $id = null;
109 2
        if (is_numeric($node)) {
110 1
            $id = $node;
111 2
        } elseif ($node instanceof Services_OpenStreetMap_Node) {
112
            $id = $node->id;
113
        } else {
114 1
            throw new Services_OpenStreetMap_InvalidArgumentException(
115
                '$node must be either ' .
116
                'an instance of Services_OpenStreetMap_Node or a numeric id'
117 1
            );
118
        }
119 1
        $pos = array_search($id, $this->nodes);
120 1
        if ($pos !== false) {
121 1
            unset($this->nodes[$pos]);
122 1
            $this->dirty  = true;
123 1
            $this->action = 'modify';
124 1
            $this->dirtyNodes = true;
125 1
        }
126 1
        return $this;
127
    }
128
129
    /**
130
     * Amend osmChangeXml with specific updates pertinent to this Way object.
131
     *
132
     * @param string $xml OSM Change XML as generated by getOsmChangeXml
133
     *
134
     * @return string
135
     * @see    getOsmChangeXml
136
     * @link   http://wiki.openstreetmap.org/wiki/OsmChange
137
     */
138
    public function osmChangeXml($xml)
139
    {
140 1
        if ($this->dirtyNodes) {
141
            $domd = new DomDocument();
142
            $domd->loadXml($xml);
143
            $xpath = new DomXPath($domd);
144
            $nodelist = $xpath->query('//' . $this->action . '/way');
145
            $nd = $xpath->query("//{$this->action}/way/nd");
146
147
            // Remove nodes if appropriate.
148
            for ($i = 0; $i < $nd->length; $i++) {
149
                $ref = $nd->item($i)->getAttribute('ref');
150
                if (array_search($ref, $this->nodes) === false) {
151
                    $nodelist->item(0)->removeChild($nd->item($i));
152
                }
153
            }
154
155
            // Add new nodes.
156
            foreach ($this->nodesNew as $new) {
157
                $el = $domd->createElement('nd');
158
                $el->setAttribute('ref', $new);
159
                $nodelist->item(0)->appendChild($el);
160
            }
161
162
            // Remove blank lines in XML - minimise bandwidth usage.
163
            return preg_replace(
164
                "/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/",
165
                '',
166
                $domd->saveXml($nodelist->item(0))
167
            );
168
169
170
            return $domd->saveXml($nodelist->item(0));
171
        } else {
172 1
            return $xml;
173
        }
174
    }
175
176
    /**
177
     * Return address [tags], as an array, if set on a closed way.
178
     *
179
     * @return array
180
     */
181
    public function getAddress()
182
    {
183 1
        if (!$this->isClosed()) {
184
            return null;
185
        }
186
187
        $ret  = array(
188 1
            'addr_housename' => null,
189 1
            'addr_housenumber' => null,
190 1
            'addr_street' => null,
191 1
            'addr_city' => null,
192
            'addr_country' => null
193 1
        );
194 1
        $tags = $this->getTags();
195 1
        $detailsSet = false;
196 1
        foreach ($tags as $key => $value) {
197 1
            if (strpos($key, 'addr') === 0) {
198 1
                $ret[str_replace(':', '_', $key)] = $value;
199 1
                $detailsSet = true;
200 1
            }
201 1
        }
202 1
        if (!$detailsSet) {
203
            $ret = null;
204
        }
205 1
        return $ret;
206
    }
207
208
}
209
// vim:set et ts=4 sw=4:
210
?>


Report generated at 2012-10-02T18:40:35+01:00